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 
相关推荐
keyipatience8 小时前
Git学习(2)撤销与分支操作全指南
大数据·elasticsearch·搜索引擎
加洛斯10 小时前
万字推演Elasticsearch修炼方法,从炼气到元婴
后端·elasticsearch·面试
说实话起个名字真难啊17 小时前
Git常用小问题笔记
笔记·git·elasticsearch
Elasticsearch18 小时前
三个区域、三个 Kibana、一个视图:跨集群搜索登陆 Elastic 合成监测
elasticsearch
keyipatience18 小时前
Git学习(3)合并冲突全解析:从原理到实战解决
大数据·elasticsearch·搜索引擎
刘老高18 小时前
微服务架构实战:ShardingSphere Proxy + Canal 分库分表与 ES 同步全链路
elasticsearch·微服务·架构
Elasticsearch18 小时前
Elastic 重大事件功能如何将 100 条日志样本转化为检测规则
elasticsearch
Elastic 中国社区官方博客2 天前
5 分钟内将 56 页扫描文档转化为带引用的答案:面向搜索无法读取的文档的检索增强生成流水线
大数据·运维·人工智能·elasticsearch·搜索引擎·信息可视化·全文检索
Elasticsearch3 天前
5 分钟内将 56 页扫描文档转化为带引用的答案:面向搜索无法读取的文档的检索增强生成流水线
elasticsearch
core5123 天前
Elasticsearch 车牌号片段搜索:n-gram 倒排索引实战方案
elasticsearch·n-gram·索引·倒排索引·号牌·片段