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值。

时间: 2024-08-13 16:51:33

Elasticsearch搜索之cross_fields分析的相关文章

Elasticsearch搜索之best_fields分析

顾名思义,best_field就是获取最佳匹配的field,另个可以通过tie_breaker来控制其他field的得分,boost可以设置权重(默认都为1). 下面从宏观上来讲的简单公式: score=best_field.score*boost+other_fields*boost.score*tie_breaker. 实际计算远比这个公式复杂得多,还要考虑分片因素.出现位置.文档长短等. 评分算法请参考:http://m.blog.csdn.net/article/details?id=5

Elasticsearch搜索之most_fields分析

顾名思义,most_field就是匹配词干的字段数越多,分数越高,也可设置权重boost. 下面是简易公式(详细评分算法请参考:http://m.blog.csdn.net/article/details?id=50623948): score=match_field1_score*boost+match_field2_score*boost+...match_fieldN_score*boost. 在很多情况下,这种搜索很有效,但存在一个弱点,就是当文档中的字段冗余信息过多,将会影响那些文档比

使用python操作elasticsearch实现数据插入分析

前言: 例行公事,有些人可能不太了解elasticsearch,下面搜了一段,大家瞅一眼. Elasticsearch是一款分布式搜索引擎,支持在大数据环境中进行实时数据分析.它基于Apache Lucene文本搜索引擎,内部功能通过ReST API暴露给外部.除了通过HTTP直接访问Elasticsearch,还可以通过支持Java.JavaScript.Python及更多语言的客户端库来访问.它也支持集成Apache Hadoop环境.Elasticsearch在有些处理海量数据的公司中已经

ELK(ElasticSearch+Logstash+Kibana)日志分析工具

日志主要包括系统日志.应用程序日志和安全日志.系统运维和开发人员可以通过日志了解服务器软硬件信息.检查配置过程中的错误及错误发生的原因.经常分析日志可以了解服务器的负荷,性能安全性,从而及时采取措施纠正错误. 通常,日志被分散的储存不同的设备上.如果你管理数十上百台服务器,你还在使用依次登录每台机器的传统方法查阅日志.这样是不是感觉很繁琐和效率低下.当务之急我们使用集中化的日志管理,例如:开源的syslog,将所有服务器上的日志收集汇总. 集中化管理日志后,日志的统计和检索又成为一件比较麻烦的事

通过HTTP RESTful API 操作elasticsearch搜索数据

通过HTTP RESTful API 操作elasticsearch搜索数据

elasticsearch搜索提示

elasticsearch搜索提示(补全)接口需要新增suggest字段并设type为:completion,结合到scrapy,修改es_types.py文件: from datetime import datetime from elasticsearch_dsl import DocType, Date, Nested, Boolean, analyzer, InnerObjectWrapper, Completion, Keyword, Text, Integer from elasti

网站基于ElasticSearch搜索的优化笔记 PHP

基本情况就是,媒体.试题.分类,媒体可能有多个试题,一个试题可能有多个分类,分类为三级分类加上一个综合属性.通过试题名称.分类等搜索查询媒体. 现在的问题为,搜索结果不精确,部分搜索无结果,ES的数据结构不满足搜索需求.解决方案就是,重构ES数据结构,采用父子关系的方式,建立media和question两个type. 全程使用https://github.com/mobz/elasticsearch-head,这个进行ES的管理和查看,很方便. 从ES的说明可以看出,ES是面向文档,其实所有的数

ElasticSearch搜索介绍四

ElasticSearch搜索 最基础的搜索: curl -XGET http://localhost:9200/_search 返回的结果为: { "took": 2, "timed_out": false, "_shards": { "total": 16, "successful": 16, "failed": 0 }, "hits": { "tota

Elasticsearch搜索结果返回不一致问题

一.背景 这周在使用Elasticsearch搜索的时候遇到一个,对于同一个搜索请求,会出现top50返回结果和排序不一致的问题.那么为什么会出现这样的问题? 后来通过百度和google,发现这是因为Elastcisearch的分布式搜索特性导致.Elasticsearch在搜索时,会循环的选择主分片和其副本中的一个来计算和返回搜索结果,而由于主分片和副本中相关统计信息的不同,从而导致了同一个搜索串的评分的不一致,进而导致排序不一样.而造成这种主分片和副本统计信息不一致的具体原因,是因为文档删除