Elasticsearch搜索之cross_fields分析
cross_fields类型采用了一种以词条为中心(Term-centric)的方法,这种方法和best_fields及most_fields采用的以字段为中心(Field-centric)的方法有很大的区别。
它将所有的字段视为一个大的字段,然后在任一字段中搜索每个词条。
operator:operator设为了and,表示所有的词条都需要出现;
minimum_should_match:表示文本匹配度,控制搜索精度,向下取整。
相比most_fields与best_fields,解释起来可能费力一些,我们不妨根据问题来引导说明。
一、cross_fields能解决什么问题?
有一类实体存储,比如人名,地址等,不是存储在单一的field里边,人名可以分为first_name,last_name。
地址有street, country, city等字段组成。这类实体查询的特殊性在于,每一个single query string都是跨越了多个字段(请仔细理解这句话)。
前边用的most_field的方法并不能满足我们的要求,会带来错误的结果。原因有几个:
1) most_field是用来找出最佳的field,这个field能满足最多的word的匹配,而不是跨越多个field去寻找最佳满足words的匹配。
2) 不能使用operator和minimum_should_match来减少相关性低的doc的长尾问题
3) 每一个field的tf是不一样的,相互之间交错会产生不好的排序结果。
most_field问题的根本原因就在于:most_field是field centric的,目的就是寻找最佳匹配的field,而我们想要的是最佳匹配的term。
best_field也存在同样问题,他们都是field centric。我们来看看问题是如何产生的,如何解决之。
(1)在多个field中匹配到同样的word
most_field实质是生成了多个match子查询,每个子查询针对一个field,然后包装成一个bool查询。
因此,如果同一个word在多个field中都出现,相比,两个word同时在一个field中出现,谁得分更高?显然是第一个,但不是我们想要的结果。
演示过程在most_field章节有具体的说明。
(2)运用operator/minimun_should_match来解决长尾
显而易见,如果指定了operator=AND,没有一个doc可以match到,从语义上也是错误的。
(3) 现在我们查询Peter Smith,在first_name和last_name中。Peter是一个很普遍的first_name,smith是一个很普遍的last_name。因此两者都具有较低的idf。
但是,如果我们有一个doc是Smith Williams?smith可是一个不常见的first_name。但 是返回结果呢?Smith Williams得分更高,但是我们要查询的是Peter Smith啊???原因就在于Smith在first_name中的高idf已经压过了peter作为一个低 idf出现在的first_name中和smith作为一个低idf出现在last_name中。
解决方案:
以上原因在于我们是在多个field中处理。因此我们只需要将多个field的信息整合成一个即可。
比如:生成一个full_name字段(可以用custom _all field的方法,mapping中设置copyto参数),包括first_name和last_name。
我们针对full_name做查询,以上三个问题就不会出现。
但是,我们存储了冗余的信息。elasticsearch考虑到这一点,提出了另外一个解决方案,就是cross fields query。
二、cross fields query
对于上述问题,custom all是一种不过的解决方案,除了冗余信息以外,这种方案是在index过程中就要指定的,有没有在查询时的解决方法呢?es提供了cross field query的解决方案。
best field 和 most field是field centric的,而cross field是term centric的。这是最大的不同。cross field把multi field 看做一整个field,在这一个field里边去match 每一个term,相当于在多个field中match。
field centric的逻辑是这样的(operator=AND):
(+first_name Peter +first_name Smith)
(+last_name Peter +last_name Smith)
term centric的逻辑是这样的(operator=AND):
+(first_name Peter last_name Peter)
+(last_name Smith last_name Smith)
也就是说peter必须出现在其中一个字段中,同时smith也必须出现在其中一个字段中。
所以cross field其实是首先分析query string 产生一个 term list,针对每一个term在任何一个field中match。
因为6中问题1 问题2就解决了,问题3呢?
cross field 在field之间把inf混合起来,作为一个整体。
+blended(“peter” fields:[ "first_name", "last_name"])
+blended(“smith” fields:[ "first_name", "last_name"])
也就是说同时在first_name和last_name中查询smith的idf,取最小值。这样smith作为一个普通的last_name,也作为一个普通的first_name。
问题3解决。
注意一点:cross fields search中的field要使用同样的analyzer。如果使用不同的analyzed,则会按照analyzer对fields进行分组blended,工作模式类似于best field。
比如title使用了一个analyzer,first_name 和last_name 使用了另外一个analyzer,则
(+title peter +title smitch)
(
+blended(“peter” fields:[ "first_name", "last_name"])
+blended(“smith” fields:[ "first_name", "last_name"])
)
cross field相对于custom all的优势在于:可以在查询时指定每一个field的boost值。
Elasticsearch搜索之cross_fields分析的更多相关文章
- Elasticsearch搜索之most_fields分析
顾名思义,most_field就是匹配词干的字段数越多,分数越高,也可设置权重boost. 下面是简易公式(详细评分算法请参考:http://m.blog.csdn.net/article/detai ...
- Elasticsearch搜索之best_fields分析
顾名思义,best_field就是获取最佳匹配的field,另个可以通过tie_breaker来控制其他field的得分,boost可以设置权重(默认都为1). 下面从宏观上来讲的简单公式: scor ...
- 一次 ElasticSearch 搜索优化
一次 ElasticSearch 搜索优化 1. 环境 ES6.3.2,索引名称 user_v1,5个主分片,每个分片一个副本.分片基本都在11GB左右,GET _cat/shards/user 一共 ...
- ElasticSearch搜索介绍四
ElasticSearch搜索 最基础的搜索: curl -XGET http://localhost:9200/_search 返回的结果为: { "took": 2, &quo ...
- elasticsearch indices.recovery 流程分析(索引的_open操作也会触发recovery)——主分片recovery主要是从translog里恢复之前未写完的index,副分片recovery主要是从主分片copy segment和translog来进行恢复
摘自:https://www.easyice.cn/archives/231 elasticsearch indices.recovery 流程分析与速度优化 目录 [隐藏] 主分片恢复流程 副本分片 ...
- ElasticSearch 线程池类型分析之 ExecutorScalingQueue
ElasticSearch 线程池类型分析之 ExecutorScalingQueue 在ElasticSearch 线程池类型分析之SizeBlockingQueue这篇文章中分析了ES的fixed ...
- ElasticSearch 线程池类型分析之 ResizableBlockingQueue
ElasticSearch 线程池类型分析之 ResizableBlockingQueue 在上一篇文章 ElasticSearch 线程池类型分析之 ExecutorScalingQueue的末尾, ...
- Elasticsearch搜索资料汇总
Elasticsearch 简介 Elasticsearch(ES)是一个基于Lucene 构建的开源分布式搜索分析引擎,可以近实时的索引.检索数据.具备高可靠.易使用.社区活跃等特点,在全文检索.日 ...
- 看完这篇还不会 Elasticsearch 搜索,那我就哭了!
本文主要介绍 ElasticSearch 搜索相关的知识,首先会介绍下 URI Search 和 Request Body Search,同时也会学习什么是搜索的相关性,如何衡量相关性. Search ...
随机推荐
- 版本控制器——Egit使用方法
什么是Git Gitv是目前世界上最先进的分布式版本控制系统. 那我们为什么需要学习Git呢?因为在我们传统的java自学中,所有的项目都是自己独立开发完成,而且项目基本都是小型项目,在优化和体验上往 ...
- 定制Maven的ArcheType
根据需要定制Maven的ArcheType的好处不言而喻了,我就不再啰嗦.定制一般通过从Maven的项目构建,比手动构建省去了配置文件的编写.资源文件的复制等繁琐的操作,下面我们就说下从Maven项目 ...
- 每天一个Linux命令 1
nl命令在Linux系统中用来计算文件中行号.nl可以将输出的文件内容自动的加上行号!其默认的结果与cat -n有点不太一样,nl可以将行号做比较多的显示设计,包括位数与是否自动补齐0等等的功能. 1 ...
- swift -- 类中的方法
一. 引用类型 类 在类中定义方法 class Person { //属性 var name : String = "" //方法 //实例方法 : 在类里面创建一个方法 fun ...
- C++类对象大小的计算
(一)常规类大小计算 C++类对象计算需要考虑很多东西,如成员变量大小,内存对齐,是否有虚函数,是否有虚继承等.接下来,我将对此举例说明. 以下内存测试环境为Win7+VS2012,操作系统为32位 ...
- zTree的拖拽排序
ztree本身是可以支持拖拽的,但是却没有找到明确的支持拖拽的排序,也就是说,在拖拽过程中,需要自定义维护拖拽后的顺序并保存至后台. 在这样一个比较常规的需求情况下,网上也有朋友给出了一些解决方案,比 ...
- 使用JSON.parse(),JSON.stringify()实现对对象的深拷贝
根据不包含引用对象的普通数组深拷贝得到启发,不拷贝引用对象,拷贝一个字符串会新辟一个新的存储地址,这样就切断了引用对象的指针联系. 测试例子: var test={ a:"ss", ...
- 老司机实战Windows Server Docker:2 docker化现有iis应用的正确姿势
前言 上一篇老司机实战Windows Server Docker:1 初体验之各种填坑介绍了安装docker服务过程中的一些小坑.这一篇,我们来填一些稍大一些的坑:如何docker化一个现有的iis应 ...
- DBMS
数据库中的概念 Catalog(分类) Table(表) Column(列)或者Field(字段) Primary(主键):唯一标识数据行的一列 业务主键:有业务意义的字段做主键 逻辑主键:使用没有任 ...
- vue搭建开发环境
windows下搭建vue开发环境 一.安装node.js 安装 vue项目通常通过webpack工具来构建,而webpack命令的执行是依赖node.js环境,所以首先要安装node.js. n ...