卡桑德拉按地图查询

时间:2018-10-05 07:14:02

标签: database-design cassandra

我有一个带有以下列的表,

name text, //partition key
tags map<text, text>

我在“标签”列上还有一个二级索引。现在我想查询,

select * from <table_name> where tags contains {'a':'b','x':'y'}
  1. 有可能吗?如果没有,我可以只查询“包含{'a':'b'}”吗?
  2. 这是一个不好的设计吗?是,如何解决? (注意:名称与标签具有1-> n关系)

1 个答案:

答案 0 :(得分:2)

问题1

对于地图集合,Cassandra允许在键,值或条目上创建索引(仅适用于地图)。

因此,首先要在地图上创建索引:

CREATE INDEX <index_name> ON <table_name> (ENTRIES(<map_column>));

然后您可以查询:

SELECT * FROM <table_name> WHERE <map_column>['<map_key>'] = '<map_value>';

另一种解决方案是冻结您的集合并在其上创建索引:

CREATE INDEX <index_name> ON table (FULL(<map_column>));

然后,您可以使用以下方法查询值:

SELECT * FROM <table_name> WHERE <map_column> = ['<value>'...];

我认为上述解决方案不是很好,因为您可以轻松扫描整个群集。您的访问类型将使用索引而不是分区键。


问题2

另一种解决方案是创建一个像这样的表:

CREATE TABLE <table_name> ( key TEXT, value TEXT, name TEXT, PRIMARY KEY ((key, value), name));

键和值列将保存标签的值。它们也将是分区键,因此您可以查询数据,例如:

SELECT * FROM <table_name> WHERE key = 'key' AND value = 'value';

您将需要运行多个查询才能搜索所有标签,但是您可以在应用程序级别汇总结果。