Elasticsearch:ES|QL 中的全文搜索 - 8.17

细心的开发者如果已经阅读我前两天发布的文章 "Elastic 8.17:Elasticsearch logsdb 索引模式、Elastic Rerank 等",你就会发现在 8.17 的发布版中,有一个重要的功能发布。那就是 ES|QL 开始支持全文搜索了。在今天的文章中我们来尝试一下。

ES|QL 中新的 MATCH 和查询字符串 (QSTR) 函数的技术预览使日志搜索更加轻松直观。MATCH 使用 Lucene 匹配查询在 ES|QL 中提供全文搜索功能,而 QTSR 通过启用 Lucene 查询字符串查询来帮助更高级地过滤日志数据。

ES|QL 的全文搜索使 Discover 中的搜索更加轻松、性能更高,尤其是在处理多个术语或条件逻辑时。

ES|QL 中的这些新搜索功能提供了显着的性能改进。查询现在可以比等效 RLIKE 查询快 50 倍到 1000 倍,尤其是在较大的数据集上。将此功能添加到 ES|QL 允许你利用 Elastic 的主要优势之一 - 能够提前索引所有数据 - 从而一次性完成繁重的工作并在以后实现真正快速的全文搜索。

所有这些都与 Elasticsearch DSL 函数紧密结合,以便在搜索中实现更好的功能奇偶校验、直观性和速度。 ES|QL 还提供完整的地理搜索功能,并显著改善按距离排序的延迟。

MATCH function

警告:请勿在生产环境中使用。此功能处于技术预览阶段,可能会在未来版本中更改或删除。Elastic 将努力修复任何问题,但技术预览中的功能不受官方 GA 功能的支持 SLA 约束。

语法

参数

参数 描述
field 查询将针对的字段。
query 你希望在提供的字段中查找的文本。

支持的类型

field query result
keyword keyword boolean
keyword text boolean
text keyword boolean
text text boolean

示例

我们首先来创建如下的一个 books 索引:

json 复制代码
1.  PUT books
2.  {
3.    "mappings": {
4.      "properties": {
5.        "title": {
6.          "type": "keyword"
7.        },
8.        "author": {
9.          "type": "text"
10.        },
11.        "book_no": {
12.          "type": "long"
13.        }
14.      }
15.    }
16.  }

如上所示,我们创建了3个字段,它们分别有不同的属性。我们使用如下的命令来写入文档:

bash 复制代码
1.  PUT books/_bulk
2.  {"index": {"_id": "1"}}
3.  {"title":"Whispers of Eternity", "book_no": 2378, "author": "[Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]"}
4.  {"index": {"_id": "2"}}
5.  {"title":"The Crimson Horizon", "book_no": 2713, "author": "William Faulkner"}
6.  {"index": {"_id": "3"}}
7.  {"title":"Shadows in Bloom", "book_no": 2847, "author": "Colleen Faulkner"}
8.  {"index": {"_id": "4"}}
9.  {"title":"Echoes of Tomorrow", "book_no": 2883, "author": "William Faulkner"}
10.  {"index": {"_id": "5"}}
11.  {"title":"Beneath the Ashen Sky", "book_no": 2713, "author": "Danny Faulkner"}

我们进行如下的搜索:

python 复制代码
1.  POST _query?format=txt
2.  {
3.    "query": """
4.        FROM books
5.        | WHERE MATCH(author, "Faulkner")
6.        | KEEP book_no, author
7.        | SORT book_no
8.        | LIMIT 5
9.     """
10.  }

上面的命令得到的结果是:

yaml 复制代码
 1.      book_no    |                      author                      
2.  ---------------+--------------------------------------------------
3.  2378           |[Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]
4.  2713           |Danny Faulkner                                    
5.  2713           |William Faulkner                                  
6.  2847           |Colleen Faulkner                                  
7.  2883           |William Faulkner 

如果我们去掉那个 SORT,我们可以看到的排序结果是:

python 复制代码
1.  POST _query?format=txt
2.  {
3.    "query": """
4.        FROM books
5.        | WHERE MATCH(author, "Faulkner")
6.        | KEEP book_no, author
7.        | LIMIT 5
8.     """
9.  }

我们得到的结果是:

yaml 复制代码
 1.      book_no    |                      author                      
2.  ---------------+--------------------------------------------------
3.  2378           |[Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]
4.  2713           |William Faulkner                                  
5.  2847           |Colleen Faulkner                                  
6.  2883           |William Faulkner                                  
7.  2713           |Danny Faulkner 

我们把搜索词的大小写改一下成 "faulKner",我们看看能否得到我们想要的结果:

python 复制代码
1.  POST _query?format=txt
2.  {
3.    "query": """
4.        FROM books
5.        | WHERE MATCH(author, "faulKner")
6.        | KEEP book_no, author
7.        | LIMIT 5
8.     """
9.  }

我们得到的结果是:

yaml 复制代码
 1.      book_no    |                      author                      
2.  ---------------+--------------------------------------------------
3.  2378           |[Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]
4.  2713           |William Faulkner                                  
5.  2847           |Colleen Faulkner                                  
6.  2883           |William Faulkner                                  
7.  2713           |Danny Faulkner 

很显然,我们得到的是同样的结果,尽管我们把搜索词的大小写都改变了。

我们再次做如下的搜索:

python 复制代码
1.  POST _query?format=txt
2.  {
3.    "query": """
4.        FROM books
5.        | WHERE MATCH(author, "Danny")
6.        | KEEP book_no, author
7.        | LIMIT 5
8.     """
9.  }

我们得到的结果是:

lua 复制代码
 1.      book_no    |    author     
2.  ---------------+---------------
3.  2713           |Danny Faulkner 

很显然这次只有一个结果。但是如果我们这样来进行搜索:

python 复制代码
1.  POST _query?format=txt
2.  {
3.    "query": """
4.        FROM books
5.        | WHERE MATCH(author, "Danny Faulkner")
6.        | KEEP book_no, author
7.        | LIMIT 5
8.     """
9.  }

我们得到的结果是:

yaml 复制代码
 1.      book_no    |                      author                      
2.  ---------------+--------------------------------------------------
3.  2378           |[Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]
4.  2713           |William Faulkner                                  
5.  2847           |Colleen Faulkner                                  
6.  2883           |William Faulkner                                  
7.  2713           |Danny Faulkner 

这次得到的结果有点出乎我们的意料。我们更希望 "Danny Faulkner" 成为排名第一的结果。很显然这个结果并不是我们想要的。

我们接下来针对 keyword 字段来进行测试:

python 复制代码
1.  POST _query?format=txt
2.  {
3.    "query": """
4.        FROM books
5.        | WHERE MATCH(title, "The Crimson Horizon")
6.        | KEEP book_no, title
7.        | LIMIT 5
8.     """
9.  }

我们得到的结果是:

yaml 复制代码
 1.      book_no    |        title        
2.  ---------------+---------------------
3.  2713           |The Crimson Horizon  
4.  2713           |Beneath the Ashen Sky

很显然,第二个结果中有一个 the 匹配,所以在召回里含有这个书目。这个还是全文搜索,尽管 title 字段是 keyword。

如果我们把 The 改成 the, 我们得到的是一样的结果:

python 复制代码
1.  POST _query?format=txt
2.  {
3.    "query": """
4.        FROM books
5.        | WHERE MATCH(title, "the Crimson Horizon")
6.        | KEEP book_no, title
7.        | LIMIT 5
8.     """
9.  }

我们可以和以前不使用 MATCH function 的查询来进行比较:

python 复制代码
1.  POST _query?format=txt
2.  {
3.    "query": """
4.        FROM books
5.        | WHERE author LIKE "William *"
6.        | KEEP book_no, author
7.        | LIMIT 5
8.     """
9.  }

上面返回结果:

yaml 复制代码
 1.      book_no    |     author     
2.  ---------------+----------------
3.  2713           |William Faulkner
4.  2883           |William Faulkner

这是一种 keyword 的搜索 尽管 author 字段是 text 字段。如果我们进行如下的搜索:

python 复制代码
1.  POST _query?format=txt
2.  {
3.    "query": """
4.        FROM books
5.        | WHERE author LIKE "william *"
6.        | KEEP book_no, author
7.        | LIMIT 5
8.     """
9.  }

上面的搜索将没有任何的结果。

QSTR function

警告:请勿在生产环境中使用 VALUES。此功能处于技术预览阶段,可能会在未来版本中更改或删除。Elastic 将努力修复任何问题,但技术预览中的功能不受官方 GA 功能的支持 SLA 约束。

语法

参数

参数 描述
query Lucene 查询字符串格式的查询字符串。

描述

执行查询字符串查询。如果提供的查询字符串与行匹配,则返回 true。

query result
keyword boolean
text boolean

示例

我们使用如下的示例来进行展示:

python 复制代码
1.  POST _query?format=txt
2.  {
3.    "query": """
4.        FROM books
5.        | WHERE QSTR("author: Faulkner")
6.        | KEEP book_no, author
7.        | LIMIT 5
8.     """
9.  }

上面命令返回的结果是:

yaml 复制代码
 1.      book_no    |                      author                      
2.  ---------------+--------------------------------------------------
3.  2378           |[Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]
4.  2713           |William Faulkner                                  
5.  2847           |Colleen Faulkner                                  
6.  2883           |William Faulkner                                  
7.  2713           |Danny Faulkner 
相关推荐
**蓝桉**1 小时前
prometheus监控nginx
nginx·elasticsearch·prometheus
光影少年1 小时前
说说模块化规范?CommonJS和ES Module的区别?
前端·javascript·elasticsearch
七夜zippoe2 小时前
Elasticsearch全文搜索与数据分析实战指南
大数据·python·elasticsearch·数据分析·全文搜索
Elasticsearch4 小时前
AI agent 记忆:使用 Elasticsearch 托管记忆创建智能代理
elasticsearch
三水不滴4 小时前
Elasticsearch 实战系列(一):从核心基础概念入门到实战落地
后端·elasticsearch
三水不滴4 小时前
Elasticsearch 生产环境全栈最佳实践:从架构设计到故障排查一站式落地指南
后端·elasticsearch·搜索引擎
深念Y5 小时前
Elasticsearch 8.11 + IK 分词器安装踩坑记录
大数据·数据库·elasticsearch·中文分词·jenkins·ki分词器
weixin_448119945 小时前
Datawhale Obsidian智能体 202603作业1
大数据·elasticsearch·搜索引擎
margu_1685 小时前
【Elasticsearch】es7.2 跨集群迁移少量数据
elasticsearch
秋知叶i6 小时前
【git命令】Git 删除远程分支保姆级教程(含缓存清理 + 本地残留绝杀)
git·elasticsearch·缓存