[Elasticsearch] 多字段搜索 (四) - 跨字段实体搜索

跨字段实体搜索(Cross-fields Entity Search)

现在让我们看看一个常见的模式:跨字段实体搜索。类似person,product或者address这样的实体,它们的信息会分散到多个字段中。我们或许有一个person实体被索引如下:

{
    "firstname":  "Peter",
    "lastname":   "Smith"
}

而address实体则是像下面这样:

{
    "street":   "5 Poland Street",
    "city":     "London",
    "country":  "United Kingdom",
    "postcode": "W1V 3DG"
}

这个例子也许很像在多查询字符串中描述的,但是有一个显著的区别。在多查询字符串中,我们对每个字段都使用了不同的查询字符串。在这个例子中,我们希望使用一个查询字符串来搜索多个字段。

用户也许会搜索名为"Peter Smith"的人,或者名为"Poland Street W1V"的地址。每个查询的单词都出现在不同的字段中,因此使用dis_max/best_fields查询来搜索单个最佳匹配字段显然是不对的。

一个简单的方法

实际上,我们想要依次查询每个字段然后将每个匹配字段的分值进行累加,这听起来很像bool查询能够胜任的工作:

{
  "query": {
    "bool": {
      "should": [
        { "match": { "street":    "Poland Street W1V" }},
        { "match": { "city":      "Poland Street W1V" }},
        { "match": { "country":   "Poland Street W1V" }},
        { "match": { "postcode":  "Poland Street W1V" }}
      ]
    }
  }
}

对每个字段重复查询字符串很快就会显得冗长。我们可以使用multi_match查询进行替代,然后将type设置为most_fields来让它将所有匹配字段的分值合并:

{
  "query": {
    "multi_match": {
      "query":       "Poland Street W1V",
      "type":        "most_fields",
      "fields":      [ "street", "city", "country", "postcode" ]
    }
  }
}

使用most_fields存在的问题

使用most_fields方法执行实体查询有一些不那么明显的问题:

  • 它被设计用来找到匹配任意单词的多数字段,而不是找到跨越所有字段的最匹配的单词。
  • 它不能使用operator或者minimum_should_match参数来减少低相关度结果带来的长尾效应。
  • 每个字段的词条频度是不同的,会互相干扰最终得到较差的排序结果。
时间: 2024-10-10 16:40:23

[Elasticsearch] 多字段搜索 (四) - 跨字段实体搜索的相关文章

MyBatis学习总结(四)——解决字段名与实体类属性名不相同的冲突

在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这种情况下的如何解决字段名与实体类属性名不相同的冲突. 一.准备演示需要使用的表和数据 CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(20), order_price FLOAT ); INSERT INTO orders(order_no, order_price) VALUES('aaaa'

[Elasticsearch] 多字段搜索 (五) - 以字段为中心的查询

以字段为中心的查询(Field-centric Queries) 上述提到的三个问题都来源于most_fields是以字段为中心(Field-centric),而不是以词条为中心(Term-centric):它会查询最多匹配的字段(Most matching fields),而我们真正感兴趣的最匹配的词条(Most matching terms). NOTE best_fields同样是以字段为中心的,因此它也存在相似的问题. 首先我们来看看为什么存在这些问题,以及如何解决它们. 问题1:在多个

Elasticsearch学习之深入搜索四 --- cross-fields搜索

1. cross-fields搜索 一个唯一标识,跨了多个field.比如一个人,标识,是姓名:一个建筑,它的标识是地址.姓名可以散落在多个field中,比如first_name和last_name中,地址可以散落在country,province,city中.跨多个field搜索一个标识,比如搜索一个人名,或者一个地址,就是cross-fields搜索.初步来说,如果要实现,可能用most_fields比较合适.因为best_fields是优先搜索单个field最匹配的结果,cross-fie

C# 实体类转json数据过滤掉字段为null的字段

原文:C# 实体类转json数据过滤掉字段为null的字段 C# 实体类转json数据过滤掉字段为null的字段 语法如下: var jsonSetting = new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore}; var json = JsonConvert.SerializeObject(data,Formatting.Indented,jsonSetting) 1,null值未处理之前的数据结构

[Elasticsearch] 部分匹配 (三) - 查询期间的即时搜索

本章翻译自Elasticsearch官方指南的Partial Matching一章. 查询期间的即时搜索(Query-time Search-as-you-type) 现在让我们来看看前缀匹配能够如何帮助全文搜索.用户已经习惯于在完成输入之前就看到搜索结果了 - 这被称为即时搜索(Instant Search, 或者Search-as-you-type).这不仅让用户能够在更短的时间内看到搜索结果,也能够引导他们得到真实存在于我们的索引中的结果. 比如,如果用户输入了johnnie walker

Elasticsearch是一个分布式可扩展的实时搜索和分析引擎,elasticsearch安装配置及中文分词

http://fuxiaopang.gitbooks.io/learnelasticsearch/content/  (中文) 在Elasticsearch中,文档术语一种类型(type),各种各样的类型存在于一个索引中.你也可以通过类比传统的关系数据库得到一些大致的相似之处: 关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 行 ⇒ 列(Columns) Elasticsearch ⇒ 索引 ⇒ 类型 ⇒ 文档 ⇒ 字段(Fields)一个Elasticsearch集群可以包含多个索引(数据库),也就是说其

mybitis中对象字段与表中字段名称不匹配(复制)

开发中,实体类中的属性名和对应的表中的字段名不一定都是完全相同的,这样可能会导致用实体类接收返回的结果时导致查询到的结果无法映射到实体类的属性中,那么该如何解决这种字段名和实体类属性名不相同的冲突呢? 方法一:通过在查询的SQL语句中定义字段名的别名的方式,让字段名的别名和实体类中的属性名一致,这样就可以实现实体类属性和表字段一一对应.(通过在SQL语句中定义别名的方法实现) [html] view plain copy <select id="queryCertificationInfo

MySQL-存储引擎-创建表-字段数据类型-严格模式-字段约束-键-02

目录 扩展点 查看服务端字符.IP.端口配置 取消本次错误输入 例外情况 database 数据库操作 table 数据表操作 查看MySQL存储引擎 常见几个存储引擎 InnoDB MyISAM MEMORY BLACKHOLE 引擎对应的本地化文件 案例 基本操作 创建表的完整语法 表记录基础操作 严格模式补充 查看数据库配置中变量名包含mode的配置参数 模糊匹配 基本数据类型 数据范围 整型 TINYINT SMALLINT MEDIUMINT INT BIGINT 应用场景 结合字段验

剖析Elasticsearch集群系列之三:近实时搜索、深层分页问题和搜索相关性权衡之道

转载:http://www.infoq.com/cn/articles/anatomy-of-an-elasticsearch-cluster-part03 近实时搜索 虽然Elasticsearch中的变更不能立即可见,它还是提供了一个近实时的搜索引擎.如前一篇中所述,提交Lucene的变更到磁盘是一个代价昂贵的操作.为了避免在文档对查询依然有效的时候,提交变更到磁盘,Elasticsearch在内存缓冲和磁盘之间提供了一个文件系统缓存.内存缓存(默认情况下)每1秒刷新一次,在文件系统缓存中使