Cassandra 文档

版本

您正在查看预发布版本的文档。

CREATE INDEX

为表的单个列定义新的辅助索引 (2i) 或存储附加索引 (SAI)。

Apache Cassandra 支持在大多数列上创建辅助索引或存储附加索引,包括 PRIMARY KEY 的分区列和聚类列、集合和静态列。对于映射,您可以使用键、值或条目(键:值对)进行索引。

除以下列外,所有列数据类型都支持 SAI 索引

  • 计数器

  • 未冻结的用户定义类型 (UDT)

一个例外

当分区键仅包含一列时,您不能基于分区键定义 SAI 索引。如果您尝试在这种情况下创建 SAI 索引,SAI 会发出错误消息。

另请参阅:CREATE CUSTOM INDEX(用于存储附加索引 (SAI))、DROP INDEX

语法

BNF 定义

index_name::= re('[a-zA-Z_0-9]+')
CREATE INDEX [ IF NOT EXISTS ] <index_name>
  ON [<keyspace_name>.]<table_name>
  ( [ ( KEYS | FULL | ENTRIES ) ] <column_name>)
    //   | [ (KEYS(<map_name>)) ]
    // | [ (VALUES(<map_name>)) ]
    // | [ (ENTRIES(<map_name>)) ]
   [USING 'sai']
  [ WITH OPTIONS = { <option_map> } ];
语法图例
图例
语法约定 描述

大写

文字关键字。

小写

非文字。

< >

变量值。用用户定义的值替换。

[]

可选。方括号 ([]) 围绕可选命令参数。不要键入方括号。

( )

组。圆括号 ( ( ) ) 标识要从中选择的组。不要键入圆括号。

|

或。竖线 (|) 分隔备选元素。键入其中一个元素。不要键入竖线。

...

可重复。省略号 ( ... ) 表示您可以根据需要重复语法元素。

'<文字字符串>'

单引号 (') 必须围绕 CQL 语句中的文字字符串。使用单引号保留大写。

{ <键> : <值> }

映射集合。大括号 ({ }) 括起映射集合或键值对。冒号分隔键和值。

<数据类型2

集合、列表、映射或元组。尖括号 ( < > ) 括起集合、列表、映射或元组中的数据类型。用逗号分隔数据类型。

<cql_语句>;

结束 CQL 语句。分号 (;) 终止所有 CQL 语句。

[--]

用两个连字符 ( -- ) 分隔命令行选项和命令参数。当参数可能被误认为命令行选项时,此语法很有用。

' <<模式\> ... </模式\>> '

仅搜索 CQL:单引号 (') 围绕整个 XML 模式声明。

@<xml_实体>='<xml_实体类型>'

仅搜索 CQL:标识实体和文字值以覆盖模式和 solrConfig 文件中的 XML 元素。

必需参数

参数

描述

table_name

要索引的表的名称。

column_name

要索引的列的名称。SAI 仅允许名称中包含字母数字字符和下划线。如果您尝试在包含其他字符的列名上定义索引,SAI 会返回 InvalidRequestException,并且不会创建索引。

可选参数

参数

描述

index_name

索引的名称。用引号括起来以使用特殊字符或保留大小写。如果未指定名称,Apache Cassandra 会将索引命名为 <table_name>\_<column_name>\_idx

keyspace_name

包含要索引的表的键空间的名称。如果未指定名称,则使用当前键空间。

map_name

集合一起使用,在 CREATE TABLE …​ map(<map_name>) 中指定的 map_name 的标识符。集合类型 listset 适用常规列语法。

option_map

以 JSON 简单格式定义选项。

case_sensitive

在匹配字符串值时忽略大小写。默认值:true

normalize

当设置为 true 时,对索引字符串执行 Unicode 规范化。SAI 支持规范化形式 C (NFC) Unicode。当设置为 true 时,SAI 会将给定 Unicode 字符的不同版本规范化为单个版本,保留索引中的所有标记和符号。例如,SAI 会将字符 Å (U+212B) 更改为 Å (U+00C5)。

当实现将字符串保留在规范化形式中时,等效字符串具有唯一的二进制表示形式。请参阅 Unicode 标准附件 #15,Unicode 规范化形式

默认值:false

ascii

当设置为 true 时,SAI 会将不在基本拉丁 Unicode 块(前 127 个 ASCII 字符)中的字母、数字和符号字符转换为 ASCII 等效字符(如果存在)。例如,此选项会将 à 更改为 a。默认值:false

similarity_function

向量搜索依赖于计算向量之间的相似度或距离来识别相关匹配项。相似度函数用于计算两个向量之间的相似度。有效选项为:EUCLIDEANDOT_PRODUCTCOSINE 默认值:COSINE

使用说明

如果列已包含数据,则会在执行此语句期间对其进行索引。创建索引后,当列中的数据发生更改时,索引会自动更新。

使用 CREATE INDEX 命令进行索引可能会影响性能。在创建索引之前,请注意何时以及

限制:不支持对计数器列进行索引。

SAI 索引

您可以在表中复合分区键的列之一上定义 SAI 索引,即包含多个列的分区键。如果您需要根据这些列之一进行查询,SAI 索引是一个有用的选项。实际上,您可以根据复合分区键中的每列定义 SAI 索引(如果需要)。

根据数据库表中任何列定义一个或多个 SAI 索引允许查询使用索引列来筛选结果。

SAI 查询运算符

SAI 支持以下查询运算符,用于具有 SAI 索引的表

  • 数字:=<>>=ANDORIN

  • 字符串:=CONTAINSCONTAINS KEYANDORIN

SAI 不支持以下查询运算符,用于具有 SAI 索引的表

  • 字符串或数字:LIKE

请参阅 SAI 部分

示例

在聚类列上创建 SAI 索引

定义一个具有 复合分区键的表,然后在聚类列上创建索引。

  • CREATE TABLE

  • CREATE INDEX

  • SELECT 查询

  • SELECT 结果

CREATE TABLE IF NOT EXISTS cycling.rank_by_year_and_name (
  race_year int,
  race_name text,
  cyclist_name text,
  rank int,
  PRIMARY KEY ((race_year, race_name), rank)
);
CREATE INDEX IF NOT EXISTS rank_idx
ON cycling.rank_by_year_and_name (rank);
SELECT * FROM rank_by_year_and_name WHERE rank = 1;
 race_year | race_name                                  | rank | cyclist_name
-----------+--------------------------------------------+------+-------------------
      2014 |                        4th Tour of Beijing |    1 | Phillippe GILBERT
      2014 | Tour of Japan - Stage 4 - Minami > Shinshu |    1 |     Daniel MARTIN
      2015 |   Giro d'Italia - Stage 11 - Forli > Imola |    1 |     Ilnur ZAKARIN
      2015 | Tour of Japan - Stage 4 - Minami > Shinshu |    1 |   Benjamin PRADES

(4 rows)

在集合或列表集合上创建索引

与任何其他列一样,在集合或列表集合列上创建索引。在 CREATE INDEX 语句的末尾用圆括号括起集合列的名称。例如,将车队的集合添加到 cyclist_career_teams 表中,以索引车队集合中的数据。

  • CREATE TABLE

  • CREATE INDEX

  • SELECT 查询

  • SELECT 结果

CREATE TABLE IF NOT EXISTS cycling.cyclist_career_teams (
  id UUID PRIMARY KEY,
  lastname text,
  teams set<text>
);
CREATE INDEX IF NOT EXISTS teams_idx
ON cycling.cyclist_career_teams (teams);
SELECT * FROM cyclist_career_teams WHERE teams CONTAINS 'Rabobank-Liv Woman Cycling Team';
 id                                   | lastname        | teams
--------------------------------------+-----------------+------------------------------------------------------------------------------------------------------
 5b6962dd-3f90-4c93-8f61-eabfa4a803e2 |             VOS | {'Nederland bloeit', 'Rabobank Women Team', 'Rabobank-Liv Giant', 'Rabobank-Liv Woman Cycling Team'}
 1c9ebc13-1eab-4ad5-be87-dce433216d40 |           BRAND |   {'AA Drink - Leontien.nl', 'Leontien.nl', 'Rabobank-Liv Giant', 'Rabobank-Liv Woman Cycling Team'}
 e7cd5752-bc0d-4157-a80f-7523add8dbcd | VAN DER BREGGEN |                 {'Rabobank-Liv Woman Cycling Team', 'Sengers Ladies Cycling Team', 'Team Flexpoint'}

(3 rows)

在映射键上创建索引

您可以在map 集合键上创建索引。如果集合的 map 值存在索引,请在创建 map 集合键的索引之前删除该索引。假设 cyclist 表包含此 map 数据,其中nation 是 map 键,`Canada` 是 map 值

{'nation':'CANADA' }

要索引 map 键,请在 CREATE INDEX 语句中使用 KEYS 关键字和嵌套括号中的 map 名称。要对表运行 SELECT 查询,请在 WHERE 子句中使用CONTAINS KEY。此查询将返回在 2015 年有条目的自行车手团队。

  • CREATE TABLE

  • CREATE INDEX

  • SELECT 查询

  • SELECT 结果

CREATE TABLE IF NOT EXISTS cycling.cyclist_teams (
  id uuid PRIMARY KEY,
  firstname text,
  lastname text,
  teams map<int, text>
);
CREATE INDEX IF NOT EXISTS team_year_keys_idx
ON cycling.cyclist_teams ( KEYS (teams) );
SELECT *
FROM cycling.cyclist_teams
WHERE teams CONTAINS KEY 2015;
 id                                   | firstname | lastname   | teams
--------------------------------------+-----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 cb07baad-eac8-4f65-b28a-bddc06a0de23 | Elizabeth | ARMITSTEAD | {2011: 'Team Garmin - Cervelo', 2012: 'AA Drink - Leontien.nl', 2013: 'Boels:Dolmans Cycling Team', 2014: 'Boels:Dolmans Cycling Team', 2015: 'Boels:Dolmans Cycling Team'}
 5b6962dd-3f90-4c93-8f61-eabfa4a803e2 |  Marianne |        VOS |                                                                                                                                   {2015: 'Rabobank-Liv Woman Cycling Team'}

(2 rows)

在 map 条目上创建索引

您可以在 map 条目上创建索引。只能在没有现有索引的表的 map 列上创建 ENTRIES 索引。

要索引集合条目,请使用 ENTRIES 关键字和嵌套括号中的 map 名称。要查询表中的 map 条目,请使用带有 map 名称和值的 WHERE 子句。此查询将查找年龄相同的自行车手。

  • CREATE TABLE

  • CREATE INDEX

  • SELECT 查询

  • SELECT 结果

CREATE TABLE IF NOT EXISTS cycling.birthday_list (
  cyclist_name text PRIMARY KEY,
  blist map<text, text>
);
CREATE INDEX IF NOT EXISTS blist_idx
ON cycling.birthday_list ( ENTRIES(blist) );
SELECT *
FROM cycling.birthday_list
WHERE blist[ 'age' ] = '23';
 cyclist_name     | blist
------------------+----------------------------------------------------------
   Claudio HEINEN | {'age': '23', 'bday': '27/07/1992', 'nation': 'GERMANY'}
 Laurence BOURQUE |  {'age': '23', 'bday': '27/07/1992', 'nation': 'CANADA'}

(2 rows)

使用相同的索引查找来自同一国家的自行车手

  • CREATE TABLE

  • CREATE INDEX

  • SELECT 查询

  • SELECT 结果

CREATE TABLE IF NOT EXISTS cycling.birthday_list (
  cyclist_name text PRIMARY KEY,
  blist map<text, text>
);
CREATE INDEX IF NOT EXISTS blist_idx
ON cycling.birthday_list ( ENTRIES(blist) );
SELECT *
FROM cycling.birthday_list
WHERE blist[ 'nation' ] = 'NETHERLANDS';
 cyclist_name  | blist
---------------+--------------------------------------------------------------
 Luc HAGENAARS | {'age': '28', 'bday': '27/07/1987', 'nation': 'NETHERLANDS'}
   Toine POELS | {'age': '52', 'bday': '27/07/1963', 'nation': 'NETHERLANDS'}

(2 rows)

在 map 值上创建索引

要创建 map 值的索引,请使用 VALUES 关键字和嵌套括号中的 map 名称。要查询表,请使用带有 map 名称及其包含值的 WHERE 子句。

  • CREATE TABLE

  • CREATE INDEX

  • SELECT 查询

  • SELECT 结果

CREATE TABLE IF NOT EXISTS cycling.birthday_list (
  cyclist_name text PRIMARY KEY,
  blist map<text, text>
);
CREATE INDEX IF NOT EXISTS blist_values_idx
ON cycling.birthday_list ( VALUES(blist) );
SELECT *
FROM cycling.birthday_list
WHERE blist CONTAINS 'NETHERLANDS';
 cyclist_name  | blist
---------------+--------------------------------------------------------------
 Luc HAGENAARS | {'age': '28', 'bday': '27/07/1987', 'nation': 'NETHERLANDS'}
   Toine POELS | {'age': '52', 'bday': '27/07/1963', 'nation': 'NETHERLANDS'}

(2 rows)

在冻结集合的完整内容上创建索引

您可以在完整的 FROZEN 集合上创建索引。可以在没有现有索引的表的 set、list 或 map 列上创建 FULL 索引。

FROZEN list 的完整内容上创建索引。此示例中的表存储自行车手参加的职业胜利、大环赛和经典赛的次数。要索引集合条目,请使用 FULL 关键字和嵌套括号中的集合名称。例如,索引冻结列表 rnumbers。要查询表,请使用带有集合名称和值的 WHERE 子句。

  • CREATE TABLE

  • CREATE INDEX

  • SELECT 查询

  • SELECT 结果

CREATE TABLE IF NOT EXISTS cycling.race_starts (
  cyclist_name text PRIMARY KEY,
  rnumbers FROZEN<LIST<int>>
);
CREATE INDEX IF NOT EXISTS rnumbers_idx
ON cycling.race_starts ( FULL(rnumbers) );
SELECT *
FROM cycling.race_starts
WHERE rnumbers = [39, 7, 14];
 cyclist_name   | rnumbers
----------------+-------------
 John DEGENKOLB | [39, 7, 14]

(1 rows)