全文搜索(Full Text Search)

现在我们已经讨论了搜索结构化数据的一些简单用例,是时候开始探索全文搜索了 - 如何在全文字段中搜索来找到最相关的文档。

对于全文搜索而言,最重要的两个方面是:

相关度(Relevance)

查询的结果按照它们对查询本身的相关度进行排序的能力,相关度可以通过TF/IDF,参见什么是相关度,地理位置的邻近程度(Proximity to a Geo-location),模糊相似性(Fuzzy Similarity)或者其它算法进行计算。

解析(Analysis)

解析用来将一块文本转换成单独的,规范化的词条(Tokens),参见解析和解析器(Analysis and Analyzers),用来完成:(a)倒排索引(Inverted Index)的创建;(b)倒排索引的查询。

一旦我们开始讨论相关度或者解析,也就意味着我们踏入了查询(Query)的领域,而不再是过滤器(Filter)。

基于词条(Term-based)和全文(Full-text)

尽管所有的查询都会执行某种程度的相关度计算,并不是所有的查询都存在解析阶段。除了诸如bool或者function_score这类完全不对文本进行操作的特殊查询外,对于文本的查询可以被划分两个种类:

基于词条的查询(Term-based Queries)

类似termfuzzy的查询是不含有解析阶段的低级查询(Low-level Queries)。它们在单一词条上进行操作。一个针对词条Footerm查询会在倒排索引中寻找该词条的精确匹配(Exact term),然后对每一份含有该词条的文档通过TF/IDF进行相关度_score的计算。

尤其需要记住的是term查询只会在倒排索引中寻找该词条的精确匹配 - 它不会匹配诸如foo或者FOO这样的变体。它不在意词条是如何被保存到索引中。如果你索引了["Foo", "Bar"]到一个not_analyzed字段中,或者将Foo Bar索引到一个使用whitespace解析器的解析字段(Analyzed Field)中,它们都会在倒排索引中得到两个词条:"Foo"以及"Bar"

全文查询(Full-text Queries)

类似match或者query_string这样的查询是高级查询(High-level Queries),它们能够理解一个字段的映射:

  • 如果你使用它们去查询一个date或者integer字段,它们会将查询字符串分别当做日期或者整型数。
  • 如果你查询一个精确值(not_analyzed)字符串字段,它们会将整个查询字符串当做一个单独的词条。
  • 但是如果你查询了一个全文字段(analyzed),它们会首先将查询字符串传入到合适的解析器,用来得到需要查询的词条列表。

一旦查询得到了一个词条列表,它就会使用列表中的每个词条来执行合适的低级查询,然后将得到的结果进行合并,最终产生每份文档的相关度分值。

我们会在后续章节中详细讨论这个过程。


在很少的情况下,你才需要直接使用基于词条的查询(Term-based Queries)。通常你需要查询的是全文,而不是独立的词条,而这个工作通过高级的全文查询来完成会更加容易(在内部它们最终还是使用的基于词条的低级查询)。

如果你发现你确实需要在一个not_analyzed字段上查询一个精确值,那么考虑一下你是否真的需要使用查询,而不是使用过滤器。

单词条查询通常都代表了一个二元的yes|no问题,这类问题通常使用过滤器进行表达更合适,因此它们也能够得益于过滤器缓存(Filter Caching):

GET /_search
{"query": {"filtered": { "filter": { "term": { "gender": "female" } } } } }

match查询

在你需要对任何字段进行查询时,match查询应该是你的首选。它是一个高级全文查询,意味着它知道如何处理全文字段(Full-text, analyzed)和精确值字段(Exact-value,not_analyzed)。

即便如此,match查询的主要使用场景仍然是全文搜索。让我们通过一个简单的例子来看看全文搜索时如何工作的。

索引一些数据

首先,我们会创建一个新的索引并通过bulk API索引一些文档:

DELETE /my_index PUT /my_index
{ "settings": { "number_of_shards": 1 }} POST /my_index/my_type/_bulk { "index": { "_id": 1 }} { "title": "The quick brown fox" } { "index": { "_id": 2 }} { "title": "The quick brown fox jumps over the lazy dog" } { "index": { "_id": 3 }} { "title": "The quick brown fox jumps over the quick dog" } { "index": { "_id": 4 }} { "title": "Brown fox brown dog" }

注意到以上在创建索引时,我们设置了number_of_shards为1:在稍后的相关度坏掉了(Relevance is broken)一节中,我们会解释为何这里创建了一个只有一个主分片(Primary shard)的索引。

单词查询(Single word query)

第一个例子我们会解释在使用match查询在一个全文字段中搜索一个单词时,会发生什么:

GET /my_index/my_type/_search
{"query": {"match": { "title": "QUICK!" } } }

ES会按照如下的方式执行上面的match查询:

  1. 检查字段类型

    title字段是一个全文字符串字段(analyzed),意味着查询字符串也需要被分析。

  2. 解析查询字符串

    查询字符串"QUICK!"会被传入到标准解析器中,得到的结果是单一词条"quick"。因为我们得到的只有一个词条,match查询会使用一个term低级查询来执行查询。

  3. 找到匹配的文档

    term查询会在倒排索引中查询"quick",然后获取到含有该词条的文档列表,在这个例子中,文档123会被返回。

  4. 对每份文档打分

    term查询会为每份匹配的文档计算其相关度分值_score,该分值通过综合考虑词条频度(Term Frequency)("quick"在匹配的每份文档的title字段中出现的频繁程度),倒排频度(Inverted Document Frequency)("quick"在整个索引中的所有文档的title字段中的出现程度),以及每个字段的长度(较短的字段会被认为相关度更高)来得到。参考什么是相关度(What is Relevance?)

这个过程会给我们下面的结果(有省略):

"hits": [{"_id": "1", "_score": 0.5, "_source": { "title": "The quick brown fox" } }, { "_id": "3", "_score": 0.44194174, "_source": { "title": "The quick brown fox jumps over the quick dog" } }, { "_id": "2", "_score": 0.3125, "_source": { "title": "The quick brown fox jumps over the lazy dog" } } ]

文档1最相关,因为它的title字段短,意味着quick在它所表达的内容中占比较大。 文档3比文档2的相关度更高,因为quick出现了两次。

[Elasticsearch] 全文搜索 (一) - 基础概念和match查询相关推荐

  1. Spring和Elasticsearch全文搜索整合详解

    Spring和Elasticsearch全文搜索整合详解 一.概述 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web ...

  2. ElasticSearch 全文搜索

    ElasticSearch 全文搜索 对文档执行全文检索,包括单个或多个单词或词组查询,返回匹配条件的搜索结果. ElasticSearch 是基于Apache Lucene的搜索引擎,一个开源.免费 ...

  3. elasticsearch全文搜索

    全文搜索 全文搜索两个最重要的方面是: 相关性(Relevance) 它是评价查询与其结果间的相关程度,并根据这种相关程度对结果排名的一种能力,这种计算方式可以是 TF/IDF 方法.地理位置邻近.模 ...

  4. SpringBoot ElasticSearch 全文搜索

    2019独角兽企业重金招聘Python工程师标准>>> 一.pom.xml配置 SpringBoot版本1.5.6https://blog.csdn.net/kingice1014/ ...

  5. SpringBoot 集成 ElasticSearch 全文搜索(步骤非常的详细)

    目录 一.pom.xml配置 二.项目代码集成示例 Yml配置 存储映射实体 @Document注解 @Field注解 创建Repository 三.安装ES 下载安装ES 测试默认分词 四.Ik分词 ...

  6. 二叉树层序遍历(广度优先搜索)基础概念与经典题目(Leetcode题解-Python语言)

    二叉树的广度优先搜索即从上到下.从左到右地进行搜索,对于层序遍历(Level Order)问题,即依次遍历第一层节点.第二层节点-等,基本可以秒杀. 广度优先搜索是通过队列来实现的,python中优先 ...

  7. 帝国CMS7.5基于es(Elasticsearch)7.x的全文搜索插件

    帝国CMS7.5基于es(Elasticsearch)7.x的全文搜索插件 - GXECMS博客 一.插件演示地址 后台演示地址:https://ecms.gxecms.cf/e/admin/inde ...

  8. ElasticSearch(七) 搜索

    title: ElasticSearch(七) 搜索 tags: ElasticSearch author: Clown95 搜索 在前面,已经介绍了在ElasticSearch索引中处理数据的基础知 ...

  9. php中文搜索工具,Laravel 下 TNTSearch+jieba-PHP 实现中文全文搜索

    TNTSearch+jieba-php这套组合可以在不依赖第三方的情况下实现中文全文搜索: 特别的适合博客这种小项目: 开启php扩展 pdo_sqlite sqlite3 mbstring 开始: ...

最新文章

  1. dynamic.rnn()sequence_len理解
  2. 免费GPU支持!口罩识别、安全帽识别算法赛同步开启,丰厚奖品等你来战!
  3. [译] 机器学习可以建模简单的数学函数吗?
  4. shell编程-变量
  5. MySql数据同步(双机热备)已正式应用上平台
  6. 干货集锦:200+生信范文、30+款软件、12类图片素材PPT,今年的SCI稳了!(附下载)...
  7. 怎么写论文?写好论文的方法
  8. java生成三角网_源码:基于离散点的构TIN算法(三角网)
  9. python采用强制自动缩进使得代码具有极佳的可读性_Python简介
  10. 静态页中利用AJAX.NET实现无刷新页面
  11. linux设置ntp开机同步时间同步,linux ntp时间同步
  12. 【医院HIS系统专题】医院HIS系统应用案例及解决方案汇总贴
  13. Oracle 甩手 Java EE,Eclipse 基金会成新东家
  14. 生产企业ERP流程是什么
  15. h5在线游戏制作开发:h5模板打地鼠小游戏怎么制作?
  16. vscode 离线安装.vsix(window 全教程)
  17. linux ubuntu git报错fatal: unsafe repository git config --global --add safe.directory解决方案
  18. 在计算机里看不到硬盘的信息,检测不到硬盘,详细教您系统里找不到硬盘该怎么办...
  19. Linux PCI驱动编写
  20. oled u8g2如何显示中文(实测有效)

热门文章

  1. java 一般方法_一般覆盖Java中的方法
  2. java comparator 降序排序_【转】java comparator 升序、降序、倒序从源码角度理解
  3. 校园计算机协会简介,大学计算机协会校园活动策划书
  4. 2020黑群晖最稳定版本_80%用户的选择!win10最稳定好用的版本更新,你敢升级吗?...
  5. 类路径是什么意思_多播是什么意思 多播介绍【详解】
  6. 【完结】你对深度学习模型的理解是否足够深刻,这12篇文章可以作为一个参考...
  7. 全球及中国数字内容产业运行现状调研与盈利前景分析报告2022年
  8. 中国碳纤维风电叶片行业“十四五”发展规划及投资可行性分析报告2022-2028年版
  9. 第一章:数组与指针概念剖析
  10. centos solr 部署到 tomcat 上