计算
弹性云服务器 ECS
Flexus云服务
裸金属服务器 BMS
弹性伸缩 AS
镜像服务 IMS
专属主机 DeH
函数工作流 FunctionGraph
云手机服务器 CPH
Huawei Cloud EulerOS
网络
虚拟私有云 VPC
弹性公网IP EIP
虚拟专用网络 VPN
弹性负载均衡 ELB
NAT网关 NAT
云专线 DC
VPC终端节点 VPCEP
云连接 CC
企业路由器 ER
企业交换机 ESW
全球加速 GA
安全与合规
安全技术与应用
Web应用防火墙 WAF
企业主机安全 HSS
云防火墙 CFW
安全云脑 SecMaster
DDoS防护 AAD
数据加密服务 DEW
数据库安全服务 DBSS
云堡垒机 CBH
数据安全中心 DSC
云证书管理服务 CCM
边缘安全 EdgeSec
威胁检测服务 MTD
CDN与智能边缘
内容分发网络 CDN
CloudPond云服务
智能边缘云 IEC
迁移
主机迁移服务 SMS
对象存储迁移服务 OMS
云数据迁移 CDM
迁移中心 MGC
大数据
MapReduce服务 MRS
数据湖探索 DLI
表格存储服务 CloudTable
云搜索服务 CSS
数据接入服务 DIS
数据仓库服务 GaussDB(DWS)
数据治理中心 DataArts Studio
数据可视化 DLV
数据湖工厂 DLF
湖仓构建 LakeFormation
企业应用
云桌面 Workspace
应用与数据集成平台 ROMA Connect
云解析服务 DNS
专属云
专属计算集群 DCC
IoT物联网
IoT物联网
设备接入 IoTDA
智能边缘平台 IEF
用户服务
账号中心
费用中心
成本中心
资源中心
企业管理
工单管理
国际站常见问题
ICP备案
我的凭证
支持计划
客户运营能力
合作伙伴支持计划
专业服务
区块链
区块链服务 BCS
Web3节点引擎服务 NES
解决方案
SAP
高性能计算 HPC
视频
视频直播 Live
视频点播 VOD
媒体处理 MPC
实时音视频 SparkRTC
数字内容生产线 MetaStudio
存储
对象存储服务 OBS
云硬盘 EVS
云备份 CBR
存储容灾服务 SDRS
高性能弹性文件服务 SFS Turbo
弹性文件服务 SFS
云硬盘备份 VBS
云服务器备份 CSBS
数据快递服务 DES
专属分布式存储服务 DSS
容器
云容器引擎 CCE
容器镜像服务 SWR
应用服务网格 ASM
华为云UCS
云容器实例 CCI
管理与监管
云监控服务 CES
统一身份认证服务 IAM
资源编排服务 RFS
云审计服务 CTS
标签管理服务 TMS
云日志服务 LTS
配置审计 Config
资源访问管理 RAM
消息通知服务 SMN
应用运维管理 AOM
应用性能管理 APM
组织 Organizations
优化顾问 OA
IAM 身份中心
云运维中心 COC
资源治理中心 RGC
应用身份管理服务 OneAccess
数据库
云数据库 RDS
文档数据库服务 DDS
数据管理服务 DAS
数据复制服务 DRS
云数据库 GeminiDB
云数据库 GaussDB
分布式数据库中间件 DDM
数据库和应用迁移 UGO
云数据库 TaurusDB
人工智能
人脸识别服务 FRS
图引擎服务 GES
图像识别 Image
内容审核 Moderation
文字识别 OCR
AI开发平台ModelArts
图像搜索 ImageSearch
对话机器人服务 CBS
华为HiLens
视频智能分析服务 VIAS
语音交互服务 SIS
应用中间件
分布式缓存服务 DCS
API网关 APIG
微服务引擎 CSE
分布式消息服务Kafka版
分布式消息服务RabbitMQ版
分布式消息服务RocketMQ版
多活高可用服务 MAS
事件网格 EG
企业协同
华为云会议 Meeting
云通信
消息&短信 MSGSMS
云生态
合作伙伴中心
云商店
开发者工具
SDK开发指南
API签名指南
Terraform
华为云命令行工具服务 KooCLI
其他
产品价格详情
系统权限
管理控制台
客户关联华为云合作伙伴须知
消息中心
公共问题
开发与运维
应用管理与运维平台 ServiceStage
软件开发生产线 CodeArts
需求管理 CodeArts Req
部署 CodeArts Deploy
性能测试 CodeArts PerfTest
编译构建 CodeArts Build
流水线 CodeArts Pipeline
制品仓库 CodeArts Artifact
测试计划 CodeArts TestPlan
代码检查 CodeArts Check
代码托管 CodeArts Repo
云应用引擎 CAE
开天aPaaS
云消息服务 KooMessage
云手机服务 KooPhone
云空间服务 KooDrive

如何使用Lucene搜索索引

更新时间:2024-12-31 GMT+08:00

GeminiDB Cassandra支持Lucene搜索索引已实现多维查询、文本检索、统计分析等能力,在使用体验上和原生二级索引相似,但同时拥有了更为丰富的语法支持。

当前Cassandra二级索引的痛点

原生Cassandra中二级索引的实现其实是创建了一张隐式的表,该表的Primary Key是创建索引的列,值为对应的Primary Key,实现相对简单,因此不可避免地带来了一些约束条件:

  • 第一主键只能用“=”查询。
  • 第二主键可以使用“=、>、<、>=、<=”。
  • 索引列只支持“=”查询。
  • 删除、更新太过频繁的列不适合建立索引。
  • High-cardinality列不适合做索引。

基于以上约束,Cassandra二级索引能提供的查询功能较为局限。

Lucene搜索索引架构

关键技术点:

内嵌Lucene搜索引擎,与存储引擎搭配,实现宽表存储引擎与搜索引擎的深度融合;

SQL层统一融合,在兼容原生Cassandra语法基础上,提供多维查询、文本检索、模糊查询、统计分析等能力,全面提升用户在海量数据场景下的查询体验。

图1 Lucene搜索索引架构

Lucene搜索索引使用方式举例

图2 Lucene搜索索引使用方式

表结构示例:

CREATE TABLE example (pk1 text, pk2 bigint, ck1 int,ck2 text,col1 int, col2 int, col3 text, col4 text, PRIMARY KEY ((pk1,pk2),ck1, ck2));

四个属性列创建Lucene搜索索引:

CREATE CUSTOM INDEX index_lucene ON test.example(col1,col2,col3,col4) USING 'LuceneGlobalIndex' 
WITH OPTIONS = {
'table_tokens': '3', 
'analyzed_columns': 'col4', 
'disable_doc_value': 'col4', 
'ordered_columns': 'col3,col4', 
'ordered_sequences': 'desc,asc', 
'analyzer_class': 'StandardAnalyzer'
};
表1 可选参数OPTIONS说明

参数名

作用

table_tokens

指定初始化Lucene搜索索引分片数,不指定默认为3,分片会占用一定的cpu和内存资源,并随数据量增长而增加。

analyzed_columns

指定用于全文搜索的列。

analyzer_class

指定全文搜索使用的分词器。

中文解析器:

'analyzer_class': 'SmartChineseAnalyzer'

标准解析器:

'analyzer_class': 'StandardAnalyzer'

IK解析器:

'analyzer_class': 'IKAnalyzer'

ordered_columns

指定Lucene搜索索引默认排序,不指定时默认与cassandra排序保持一致,多个索引列通过逗号隔开,需要注意:只有查询时排序方式与默认排序一致时,查询效率最高。

ordered_sequences

指定排序索引列升降序,asc代表升序,desc代表降序,需要与ordered_columns一一对应。

disable_doc_value

指定索引列不进行DocValues存储,对于不需要进行排序、聚合等操作的索引列可以禁用DocValues存储。

多维查询:任意索引列组合的嵌套查询,支持精确查询和范围查询。

SELECT * from example WHERE pk1>='a' and pk2>=1000 and ck2 in ('a','b','c') and col1 <= 4 and col2 >= 2;

count计数:获取数据表的总行数,或根据索引列具体查询条件返回命中的数据行数。

SELECT count(*) FROM example WHERE col1 > 3 AND EXPR(index_lucene, 'count');

索引列排序支持指定多个索引列排序规则,结合多维查询,返回指定排序的结果集。(通过JSON扩展语义支持,见下一节扩展JSON语义

模糊查询:支持前缀查询和通配符查询。

SELECT * FROM example WHERE col3 LIKE 'test%'; 
SELECT * FROM example WHERE col3 LIKE 'start*end';

聚合分析:按照索引列组合条件进行简单的聚合分析(sum/max/min/avg)

SELECT sum(col1) from example WHERE pk1>='a' and pk2>=1000 and col1 <= 4 and col2 >= 2;

全文检索:支持指定中/英文分词器,进行分词检索,返回相关性高的结果。

SELECT * FROM example WHERE col4 LIKE '%+test -index%';

扩展JSON语义:

表2 扩展JSON语义

关键字

作用

filter

在查询语句中json查询的关键字。

term

查询时判断某个document是否包含某个具体的值。

match

将被询值进行分词,进行全文检索。

range

查询指定某个字段在某个特定的范围。(范围查询子关键字:"eq"/"gte"/"gt"/"lte"/"lt")

bool

必须和 "must"、"should"、"must not" 一起组合出复杂的查询。

must

bool类型的子查询,封装"term"、"match"、"range" 查询。

should

bool类型的子查询,封装"term"、"match"、"range" 查询。

must not

bool类型的子查询,封装"term"、"match"、"range" 查询。

sort

支持全局索引列排序功能。

典型JSON查询语句示例:

{
  "filter": {
    "bool": {
      "should": [
        {"term": {"col1": 1, "col1": 2, "col1": 3, "col3": "testcase7"}}
      ], 
      "must": [
        {"range": {"col2": {"lte": 7, "gt": 0}, "ck1": {"gte": 2}}},
        {"match": {"col4": "+lucene -index"}}
      ]
    }
  }, 
  "sort": [{"col1":"desc"}, {"col2":"asc"}]
}

完整cql如下:

SELECT * from example where expr(index_lucene, '{"filter": {"bool": {"should": [{"term": {"col1": 1, "col1": 2, "col1": 3, "col3": "testcase7"}}], "must": [{"range": {"col2": {"lte": 7, "gt": 0}, "ck1": {"gte": 2}}},{"match": {"col4": "+lucene -index"}}]}}, "sort": [{"col1":"desc"}, {"col2":"asc"}]}');

下面对典型的查询场景cql语句结合JSON一起进行对比举例:

1. 带分区键的查询(指定pk1、pk2),需要将pk1和pk2从json条件中剥离出来,否则会影响性能。

SELECT * from example where pk1=*** and pk2=*** and expr(index_lucene, 'json');

2. 查询条件: col1=1。

SELECT * from example WHERE col1=1;
SELECT * from example WHERE expr(index_lucene, '{"filter": {"term": {"col1": 1}}}');
SELECT * from example WHERE expr(index_lucene, '{"filter": {"bool": {"must": [{"term": {"col1": 1}}]}}}');

上面三条语句,是等效的;类似这种情况,建议使用第一种的普通cql查询,只有当普通cql无法支持时,再使用json扩展查询;上面三个语句推荐顺序次为从上到下。

3. 查询条件:col1=1 and col2>=2。

SELECT * from example WHERE col1=1 and col2>=2;
SELECT * from example WHERE expr(index_lucene, '{"filter": {"term": {"col1": 1},"range": {"col2": {"gte": 2}}}}');
SELECT * from example WHERE expr(index_lucene, '{"filter": {"bool": {"must": [{"term": {"col1": 1}}, {"range": {"col2": {"gte": 2}}}]}}}');

与第一种相同,推荐普通cql查询。

4. 查询条件:col1=1 and (col2<2 or col2>3)。

SELECT * from example WHERE expr(index_lucene, '{"filter": {"bool": {"must": [{"term": {"col1": 1}}], "should": [{"range": {"col2": {"lt": 2}, "col2": {"gt": 3}}}]}}}');
SELECT * from example WHERE expr(index_lucene, '{"filter": {"bool": {"must": [{"term": {"col1": 1}}], "must_not": [{"range": {"col2": {"gte": 2, "lte": 3}}}]}}}');

上面两种方式效果相同,但是不推荐使用"must_not",性能不如"should"。

5. 查询条件:col1 in (1,2,3,4) and (col2<2 or col2>3)。

SELECT * from example WHERE expr(index_lucene, '{"filter": {"bool": {"should": [{"term": {"col1": 1, "col1": 2, "col1": 3, "col1": 4}}], "should": [{"range": {"col2": {"lt": 2}, "col2": {"gt": 3}}}]}}}');
SELECT * from example WHERE expr(index_lucene, '{"filter": {"bool": {"should": [{"term": {"col1": 1, "col1": 2, "col1": 3, "col1": 4}}], "must_not": [{"range": {"col2": {"gte": 2, "lte": 3}}}]}}}');

与4一样,上面两种方式效果相同,但是不推荐使用"must_not",性能不如"should"。

6. 带分区键single查询:pk1='a' and pk2=1000 and col1 in (1,2,3,4) and (col2<2 or col2>3)。

SELECT * from example WHERE pk1='a' and pk2=1000 and expr(index_lucene, '{"filter": {"bool": {"should": [{"term": {"col1": 1, "col1": 2, "col1": 3, "col1": 4}}], "should": [{"range": {"col2": {"lt": 2}, "col2": {"gt": 3}}}]}}}');

7. 查询条件:(((ck1<2 or ck1>=4) and (col1<2 or col1 >3)) or (pk1 in ('a', 'b', 'c'))) or (5<=col2<15 and pk2 > 2000)。

SELECT * from example WHERE expr(index_lucene, '{"filter": {"bool": {"should": [{"bool": {"should": [{"bool": {"must": [{"bool": {"should": [{"range": {"ck1": {"lt": 2}, "ck1": {"gte": 4}}}]}}, {"bool": {"should": [{"range": {"col1": {"lt": 2}, "col1": {"gt": 3}}}]}}]}}, {"bool": {"should": [{"term": {"pk1": "a", "pk1": "b", "pk1": "c"}}]}}]}}, {"bool": {"must": [{"range": {"col2": {"gte":5, "lte": 15}, "pk2": {"gt": 2000}}}]}}]}}}');

8. count 查询,也可使用json构造查询条件,上面的查询条件,进行count查询,语句如下

SELECT count(*) from example WHERE expr(index_lucene, '{"filter": {"bool": {"should": [{"bool": {"should": [{"bool": {"must": [{"bool": {"should": [{"range": {"ck1": {"lt": 2}, "ck1": {"gte": 4}}}]}}, {"bool": {"should": [{"range": {"col1": {"lt": 2}, "col1": {"gt": 3}}}]}}]}}, {"bool": {"should": [{"term": {"pk1": "a", "pk1": "b", "pk1": "c"}}]}}]}}, {"bool": {"must": [{"range": {"col2": {"gte":5, "lte": 15}, "pk2": {"gt": 2000}}}]}}]}}}');

注意事项:

  • 普通cql可以满足的查询条件,尽量避免依赖json查询。
  • 单分区查询,要将分区键条件单独作为查询条件,不要放入json中,否则会影响single查询的性能。
  • 尽量避免使用"must_not"。
  • 如果查询总是需要按照某些索引列排序输出,可以考虑在创建索引时指定该排序方式为默认排序以提升性能。

我们使用cookie来确保您的高速浏览体验。继续浏览本站,即表示您同意我们使用cookie。 详情

文档反馈

文档反馈

意见反馈

0/500

标记内容

同时提交标记内容