天天看点

elasticsearch单字符串多字段查询(Dis Max Query&multi match)

################单字符串多字段查询:Dis Max Query######

使⽤ bool 查询实现单字符串多字段查询

##● 单字符串多字段查询时,如何在多个字段上进⾏算分
##● 复合查询:Disjunction Max Query
##● 将评分最⾼的字段评分作为结果返回,满⾜两个字段是竞争关系的场景
##● 对最佳字段查询进⾏调优:通过控制 Tie Breaker 参数,引⼊其他字段对算分的⼀些影响
DELETE blogs

PUT /blogs/_doc/1
{
    "title": "Quick brown rabbits",
    "body":  "Brown rabbits are commonly seen."
}

PUT /blogs/_doc/2
{
    "title": "Keeping pets healthy",
    "body":  "My quick brown fox eats rabbits on a regular basis."
           

}

使用bool查询实现单个字符串在多字段查询 会查询should语句中的俩个查询,然后将俩个查询的评分相加

POST blogs/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "Brown fox"
          }
        },
        {
          "match": {
            "body": "Brown fox"
          }
        }
      ]
    }
  }
}
           

而title和body属于相互竞争,我们可以使用dis_max query 将任何与任一查询匹配的文档作为结果返回,采用字段上最匹配的评分最终评分返回

Tier Breaker 是⼀个介于 0-1 之间的浮点数。0

代表使⽤最佳匹配;1 代表所有语句同等重要。

POST blogs/_search
{
  "query": {
    "dis_max": {
      "tie_breaker": 0.2,
      "boost": 1.2,
      "queries": [
        {
          "match": {
            "title": "Brown fox"
          }
        },
        {
          "match": {
            "body": "Brown fox"
          }
        }
      ]
    }
  }
}
           

##################单字符串多字段查询:Multi Match###########

multi match 多字段查询, 有三种类型可以选择

最佳字段(best fields) 当字段之间相互竞争,又相互关联 例如 title和body 这样的字段。我们就可以使用best fields 选择评分来自最匹配字段

多数字段 most fields 处理英⽂内容时:⼀种常⻅的⼿段是,在主字段( English Analyzer),抽取词⼲,加⼊同义词,以匹配更多的⽂档。相同的⽂本,加⼊⼦字段(Standard Analyzer),以提供更加精确的匹配。其他字段作为匹配⽂档提⾼相关度的信号。匹配字段越多则越好

混合字段 cross fields

对于某些实体,例如人名,地址,图书信息,需要在多个字段中确定信息,单个字段只能作为整体的一部分,希望在任何这些列出的字段中找到竟可能多的词

multi match query

best fields 是默认类型 可以不用指定 Minimum should match 等参数可以传递到⽣成的 query中

POST blogs/_search
{
  "query": {
    "multi_match": {
      "query": "Quick pets",
      "fields": [
        "title",
        "body"
      ],
      "type": "best_fields",
      "tie_breaker": 0.2,
      "minimum_should_match": "20%"
    }
  }
}

DELETE titles
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 " }

### 默认情况下,english分词器会将文档进行处理,所以文档1和文档2在处理后得到的得分是一样的,但是如果我们想要精确匹配"barking dogs" 并且得到完全匹配他最高的得分的数据排序,
GET titles/_search
{
  "query": {
    "match": {
      "title": "barking dogs"
    }
  }
}


PUT titles
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "english",
        "fields": {
          "std": {
            "type": "text",
            "analyzer": "standard"
          }
        }
      }
    }
  }
}
           

⽤⼴度匹配字段 title 包括尽可能多的⽂档——以提升召回率——同时⼜使⽤字段 title.std 作为信号 将相关度更⾼的⽂档置于结果顶部。

####● 每个字段对于最终评分的贡献可以通过⾃定义值 boost 来控制。⽐如,使 title 字段更为重要,这样同时也降低了其他信号字段的作⽤:

现在得到的得分就是完全匹配 “barking dogs”, 的得分就会排到前面,其他符合条件的数据也会正常出现

GET titles/_search
{
  "query": {
    "multi_match": {
      "query": "barking dogs",
      "type": "most_fields",
      "fields": [
        "title",
        "title.std"
      ]
    }
  }
}

## multi match 跨字段查询 cross_fileds
### 可以使用copy_to 完成跨字段的查询,但是需要额外的存储空间 而multi match的跨字段查询支持operator 还有一个优势就是可以在搜索时为单个字段提示权重

GET titles/_search
{
  "query": {
    "multi_match": {
      "type": "cross_fileds", 
      "query": "###",
      "fields": ["###","###"]
    }
  }
}
           

继续阅读