目录

单字符串查询实例 

bool查询should的算分过程

Disjunction Max Query查询

通过Tie Breaker参数调整

MultiMatch Query查询

三种场景

 MultiMatch Query语法

 使用多数字段匹配解决

跨字段搜索(一个地址信息映射到不同的字段上:街道,城市,国家......)

单字符串查询实例 

PUT /blogs/_bulk
 {"index":{"_id":1}}
 {"title":"Qucik brown rabbits","body":"Brown rabbits are commonly"}
 {"index":{"_id":2}}
 {"title":"Keeping pets healthy","body":"My quick brown fox eats rabbits on a regualr basis."} POST /blogs/_search
 {
   "query":{
     "bool": {
       "should": [
         {"match": {
           "title": "Brown fox"
         }},
         {
           "match": {
           "body": "Brown fox"
         }
         }
       ]
     }
   }
 }

es某字段搜索多个关键字 es查询多个字段_搜索

bool查询should的算分过程

  • 查询should语句中的两个查询
  • 加和两个查询的评分
  • 乘以匹配语句的总数
  • 除以所有语句的总数
  • 文档1的标题和内容都包含了brown,文档2的内容包含了brown fox有更高的相似度,但是在title中算分很低.当两者相加的时候会出现文档1的打分比文档2的打分高

Disjunction Max Query查询

  • 上述中,title和body相互竞争
  • 不应该将分数简单叠加,而是应该找到单个最佳匹配的字段的评分
  • Disjunction Max Query
  • 将任何与任一查询匹配的文档作为结果返回,采用字段上最匹配的评分最终评分返回
GET /blogs/_search
 {
   "query": {
     "dis_max": {
       "queries": [
         {"match": {"title": "brown fox"}},
         {"match": {"body": "brown fox"}}
         ]
     }
   }
 }

es某字段搜索多个关键字 es查询多个字段_Max_02

通过Tie Breaker参数调整

  • 获得最佳匹配语句的评分_score
  • 将其他匹配的评分与tie_breaker相乘
  • 对以上评分求和并规范化
  • Tie Breaker是一个介于0-1之间的浮点数.0代表使用最佳匹配;1代表所有语句同等重要
  • 布尔查询用should方式进行,它是将各个字段上的评分进行一个简单的加和,当处理特殊的竞争字段的时候返回的算分并不满足我们的期望,通过引入一个复合查询Disjunction Max Query,返回字段当中评分最高的作为整体的算分;需要在Disjunction Max Query的时候引入一些其他算分的影响的时候,我们可以通过Tie Breaker的参数对算分进行一些适当的调整

MultiMatch Query查询

三种场景

  • 最佳字段
  • 当字段之间相互竞争,又相互关联.例如title和body这样的字段.评分来自最匹配字段
  • 多数字段
  • 处理应为内容时:一种常见的手段是,在主字段.抽取词干,加入同义词,以匹配更多的文档.相同的文本,加入子字段,以提供更加准确的匹配.其他字段作为匹配文档提供相关度的信号.匹配字段越多越好
  • 混合字段
  • 对于某些实体,例如人名,地址,图书信息.需要在多个字段中确定信息,单个字段只能作为整体的一部分,希望在任何这些列出的字段中找到尽可能多的词.

 MultiMatch Query语法

es某字段搜索多个关键字 es查询多个字段_Max_03

 

  • Best Fields 是默认类型,可以不指定
  • Minimum should match 等参数可以传递到生成的query中
PUT /titles
 {
   "mappings": {
     "properties": {
       "title":{
         "type": "text"
         , "analyzer": "english"
       }
     }
   }
 }POST titles/_bulk
 {"index":{"_id":1}}
 {"title":"My dog barks"}
 {"index":{"_id":2}}
 {"title":"I see a lot of barking dogs on the road"}

es某字段搜索多个关键字 es查询多个字段_字段_04

 

  • 原因分析:我们的title采用英文分词器,会将barking dogs分成两个term,因为文档1更短,所以文档1的算分更高 
  • 英文分词器会对时态做一个词干的提取
  • 对上述文档做优化.为 title增加一个子字段,分词器为standard(不会对词干提取,不会损失一些相关的信息);英文分词器可以提升搜索的record的值;standard控制搜索条件的精度
  • multi_match可以指定一个type.most_fields可以把"title","title.std"的算分做一个叠加,将最匹配的结果显示在第一位
PUT /titles
 {
   "mappings": {
     "properties": {
       "title":{
         "type": "text"
         , "analyzer": "english",
         "fields": {
           "std":{
             "type":"text",
             "analyzer":"standard"
           }
         }
       }
     }
   }
 }POST titles/_search
 {
   "query":{
     "multi_match": {
       "query": "barking dogs",
       "fields": ["title","title.std"],
       "type": "most_fields"
     }
   }
 }

es某字段搜索多个关键字 es查询多个字段_搜索_05

 使用多数字段匹配解决

  • 用广度匹配字段title包括尽可能多的文档--以提升召回率--同时有使用字段title.std作为信号将相关度更高的文档置于结果顶部.
  • 每个字段对于最终评分的贡献可以通过自定义值boost来控制.比如,使title字段更为重要,这样也降低了其他信号字段的作用
  • 在字段filed当中增加一个权重来控制最终结果的一个返回 

es某字段搜索多个关键字 es查询多个字段_Max_06

跨字段搜索(一个地址信息映射到不同的字段上:街道,城市,国家......)

es某字段搜索多个关键字 es查询多个字段_Max_07

  • 可以用copy_to解决,但是需要额外的存储空间
  • 一个详细的地址信息完全映射到不同的字段上,不能通过增加Operator:and来满足这个条
  • 解决办法:cross_fields
  • type为cross_fields且指定operator为"and",query里面的词都必须出现在fields字段当中(不用每个字段都包含query,指定的字段加起来包含query就行)
  • 支持使用Operator
  • 与copy_to相比,其中一个优势就是他可以在搜索时为单个字段提升权重

 

PUT address/_doc/1
 {
   "street":"5 Poland Street",
   "city":"London",
   "country":"United Kingdom",
   "postcode":"W1V 3DG"
 }POST address/_search
 {
   "query":{
     "multi_match": {
       "query": "Poland Street W1V",
       "fields": ["street","city","country","postcode"]
       , "type": "most_fields"
     }
   }
 }

es某字段搜索多个关键字 es查询多个字段_elasticsearch_08

 

es某字段搜索多个关键字 es查询多个字段_elasticsearch_09

es某字段搜索多个关键字 es查询多个字段_字段_10