elasticsearch best_fields most_fields cross_fields从内在实现看区别——本质就是前两者是以field为中心,后者是词条为中心
1.最佳字段(Best fields)::
假设我们有一个让用户搜索博客文章的网站(允许多字段搜索,最佳字段查询),就像这两份文档一样:
PUT /my_index/my_type/1
{
"title": "Quick brown rabbits",
"body": "Brown rabbits are commonly seen."
}
PUT /my_index/my_type/2
{
"title": "Keeping pets healthy",
"body": "My quick brown fox eats rabbits on a regular basis."
}
// SENSE: 110_Multi_Field_Search/15_Best_fields.json
用户输入了"Brown fox",文档2匹配的更好一些,因为它包含了用户寻找的两个单词。
{
"multi_match": {
"query": "Quick brown fox",
"type": "best_fields", <1>
"fields": [ "title", "body" ],
"tie_breaker": 0.3,
"minimum_should_match": "30%" <2>
}
}
2.多数字段(Most fields)::
一个用来调优相关度的常用技术是将相同的数据索引到多个字段中。它用来尽可能多地匹配文档。
考虑一下most_fields查询是如何执行的:ES会为每个字段生成一个match查询,然后将它们包含在一个bool查询中。
我们可以将查询传入到validate-query API中进行查看:
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "Poland Street W1V",
"type": "most_fields",
"fields": [ "street", "city", "country", "postcode" ]
}
}
}
// SENSE: 110_Multi_Field_Search/40_Entity_search_problems.json
它会产生下面的解释(explaination):
(street:poland street:street street:w1v)
(city:poland city:street city:w1v)
(country:poland country:street country:w1v)
(postcode:poland postcode:street postcode:w1v)
你可以发现能够在两个字段中匹配poland的文档会比在一个字段中匹配了poland和street的文档的分值要高。
3.跨字段(Cross fields)::
对于一些实体,标识信息会在多个字段中出现,每个字段中只含有一部分信息:
- Person:
first_name和last_name - Book:
title,author, 和description - Address:
street,city,country, 和postcode
此时,我们希望在任意字段中找到尽可能多的单词。我们需要在多个字段中进行查询,就好像这些字段是一个字段那样。
用户也许会搜索名为"Peter Smith"的人,或者名为"Poland Street W1V"的地址。每个查询的单词都出现在不同的字段中。
如果你在索引文档前就能够自定义_all字段的话,那么使用_all字段就是一个不错的方法。但是,ES同时也提供了一个搜索期间的解决方案:使用类型为cross_fields的multi_match查询。cross_fields类型采用了一种以词条为中心(Term-centric)的方法,这种方法和best_fields及most_fields采用的以字段为中心(Field-centric)的方法有很大的区别。它将所有的字段视为一个大的字段,然后在任一字段中搜索每个词条。
为了阐述以字段为中心和以词条为中心的查询的区别,看看以字段为中心的most_fields查询的解释(译注:通过validate-query API得到):
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "most_fields",
"operator": "and", <1>
"fields": [ "first_name", "last_name" ]
}
}
}
// SENSE: 110_Multi_Field_Search/50_Cross_field.json
<1> operator设为了and,表示所有的词条都需要出现。
对于一份匹配的文档,peter和smith两个词条都需要出现在相同的字段中,要么是first_name字段,要么是last_name字段:
(+first_name:peter +first_name:smith)
(+last_name:peter +last_name:smith)
而以词条为中心的方法则使用了下面这种逻辑:
+(first_name:peter last_name:peter)
+(first_name:smith last_name:smith)
换言之,词条peter必须出现在任一字段中,同时词条smith也必须出现在任一字段中。
cross_fields类型首先会解析查询字符串来得到一个词条列表,然后在任一字段中搜索每个词条。仅这个区别就能够解决在以字段为中心的查询中提到的3个问题中的2个,只剩下倒排文档频度的不同这一问题。
幸运的是,cross_fields类型也解决了这个问题,从下面的validate-query请求中可以看到:
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "cross_fields", <1>
"operator": "and",
"fields": [ "first_name", "last_name" ]
}
}
}
// SENSE: 110_Multi_Field_Search/50_Cross_field.json
<1> cross_fields 使用以词条为中心(Term-centric)进行匹配。
它通过混合(Blending)字段的倒排文档频度来解决词条频度的问题:
+blended("peter", fields: [first_name, last_name])
+blended("smith", fields: [first_name, last_name])
换言之,它会查找词条smith在first_name和last_name字段中的IDF值,然后使用两者中较小的作为两个字段最终的IDF值。因为smith是一个常见的姓氏,意味着它也会被当做一个常见的名字。
提示:为了让cross_fields查询类型能以最佳的方式工作,所有的字段都需要使用相同的解析器。使用了相同的解析器的字段会被组合在一起形成混合字段(Blended Fields)。
如果你包含了使用不同解析链(Analysis Chain)的字段,它们会以和best_fields相同的方式被添加到查询中。比如,如果我们将title字段添加到之前的查询中(假设它使用了一个不同的解析器),得到的解释如下所示:
(+title:peter +title:smith)
(
+blended("peter", fields: [first_name, last_name])
+blended("smith", fields: [first_name, last_name])
)
当使用了minimum_should_match以及operator参数时,这一点尤为重要。
摘自:https://es.xiaoleilu.com/110_Multi_Field_Search/50_Cross_field.html
elasticsearch best_fields most_fields cross_fields从内在实现看区别——本质就是前两者是以field为中心,后者是词条为中心的更多相关文章
- Elasticsearch搜索之cross_fields分析
cross_fields类型采用了一种以词条为中心(Term-centric)的方法,这种方法和best_fields及most_fields采用的以字段为中心(Field-centric)的方法有很 ...
- C、C++、C#、Java、php、python语言的内在特性及区别
C.C++.C#.Java.PHP.Python语言的内在特性及区别: C语言,它既有高级语言的特点,又具有汇编语言的特点,它是结构式语言.C语言应用指针:可以直接进行靠近硬件的操作,但是C的指针操作 ...
- docker+springboot+elasticsearch+kibana+elasticsearch-head整合(详细说明 ,看这一篇就够了)
一开始是没有打算写这一篇博客的,但是看见好多朋友问关于elasticsearch的坑,决定还是写一份详细的安装说明与简单的测试demo,只要大家跟着我的步骤一步步来,100%是可以测试成功的. 一. ...
- 【Elasticsearch 技术分享】—— 十张图带大家看懂 ES 原理 !明白为什么说:ES 是准实时的!
前言 说到 Elasticsearch ,其中最明显的一个特点就是 near real-time 准实时 -- 当文档存储在Elasticsearch中时,将在1秒内以几乎实时的方式对其进行索引和完全 ...
- Java调用Elasticsearch API查询及matchPhraseQuery和matchQuery的区别
一.引入依赖 <!--Elasticsearch client--> <!-- https://mvnrepository.com/artifact/org.elasticsearc ...
- 【ElasticSearch】ES5新特性-keyword-text类型-查询区别
ES5新特性-keyword-text类型-查询区别 elasticsearch-head Elasticsearch-sql client junneyang (JunneYang) es keyw ...
- 再看.net本质(二)
3.[HTTP协议] 当浏览器寻找到Web服务器的地址之后,浏览器将帮助我们把对服务器的请求转换为一系列参数发送给Web服务器.服务器收到浏览器的请求对数之后,将会分析这些数据并进行处理,然后向浏览 ...
- 再看.net本质
1.[资源的地址-通用资源标识符] 我们在地址栏中输入的内容称为通用资源标识符(Universal Resource Identifier,URI),它有很多种形式,在Web中我们通常使用称为统一资源 ...
- 福利,一张图看懂IT售前工程师修炼之道
职场中的新人如何自我定位? 如何深刻理解IT售前这个职位? 如何从IT售前菜鸟成长为IT售前专家? 推荐这本书<IT售前工程师修炼之道> 本书精华内容 售前的重要性 售前要有逻辑能力 售前 ...
随机推荐
- PHP 高效导入导出Excel(csv)方法之fgetcsv()和fputcsv()函数
CSV,是Comma Separated Value(逗号分隔值)的英文缩写,通常都是纯文本文件. 一.CSV数据导入函数fgetcsv() fgetcsv() 函数从文件指针中读入一行并解析 CSV ...
- TensorFlow学习入门
学习了基本的神经网络知识后,要使用框架了,这样才能出来更加复杂的情况,更快的开发出模型. 首先安装后,按照官网写了一个例子,但是又好多不懂,但只是第一步, 看这段代码,其实给你提供了很多学习tf的线索 ...
- python生成组织架构图(网络拓扑图、graph.editor拓扑图编辑器)
Graph.Editor是一款基于HTML5技术的拓补图编辑器,采用jquery插件的形式,是Qunee图形组件的扩展项目,旨在提供可供扩展的拓扑图编辑工具, 拓扑图展示.编辑.导出.保存等功能,此外 ...
- linux的基本操作(文件压缩与打包)
文件的压缩与打包 在windows下我们接触最多的压缩文件就是.rar格式的了.但在linux下这样的格式是不能识别的,它有自己所特有的压缩工具.但有一种文件在windows和linux下都能使用那就 ...
- 记一次GRPC使用报错排查
项目一直使用grpc作为服务交互程序,其中我负责的java模块第一次引用该框架:当框架搭建好后,建立客户端代码,报错: Runable Error:java.lang.IllegalAccessErr ...
- ajax里post 设置请求头的编码格式
我们常用的ajax形式就是post和get.post需要设置请求头,那么问题来了: 首先,为什么get不需要设置编码格式? 其次:不设置post请求头编码格式可以吗? 还有:常用的请求头编码格式有哪些 ...
- 用vue制作饿了么首页(1)
无论是静态网页还是动态交互网页,实现原则是将他们分块,然后各个击破. 很明显的饿了么首页分为三个部分(组件), 上面的头部(商家信息), 中间路由 购物车 每部分先占住自己位置,然后挨个将这三部分分别 ...
- js的小知识7
1.函数都有返回值...... 而方法的本质也是函数,所有也有返回值. Document.getElementById()返回的是获取的标签 getElementByClassName()和getEl ...
- iOS 调试 crash breakpoint EXC_BAD_ACCESS SIGABRT
原文地址:iOS 调试 crash breakpoint EXC_BAD_ACCESS SIGABRT作者:流年若离殇 在调试程序的时候,总是碰到crash的bug,而且一追踪就是一些汇编的代码,让人 ...
- ES6 Class 类
在ES6中,class (类)作为对象的模板被引入,可以通过 class 关键字定义类. class 的本质是 function. 它可以看作一个语法糖,让对象原型的写法更加清晰.更像面向对象编程的语 ...