重生之我们在ES顶端相遇第3章-我学会了全文搜索!!!

前置

上篇章,介绍了 ES 基本的增删改查。本篇章,将介绍 ES 的全文搜索(full text query),term query 会放到下一章节介绍。

Intervals query

被搜索的关键字,要按照指定的顺序出现在文档中,该文档才能被检索。

例如。

PUT /test/_doc/1
{
  "name": "do you like search? yes. i am. i like java"
}

GET /test/_search
{
  "query": {
    "intervals": {
      "name": {
        "all_of": {
          "ordered": true,
          "intervals": [
            { "match": { "query": "am" }},
            { "match": { "query": "i" }},
            { "match": { "query": "java" }}
          ]
        }
      }
    }
  }
}

该查询的意思为,文档中需要有对应的term, am i java,且必须按照 am > i > java 的顺序出现。

match query

先对搜索词进行分词,然后再搜索。

例如

PUT /test/_doc/2
{
  "name": "PHP is the best language in the world"
}
PUT /test/_doc/3
{
  "name": "hello world! elasticsearch!"
}

GET /test/_search
{
  "query": {
    "match": {
      "name": "php"
    }
  }
}

心细如你的一定可以发现,输入的 PHP 是大写。但小写也可搜索到。这部分内容和分词有关系,后续会补充,这里先忽略。

Match boolean prefix query

前缀匹配。将搜索词分词,最后一个词,被用作前缀匹配。

GET /test/_search
{
  "query": {
    "match_bool_prefix": {
      "name": {
        "query": "search wor",
        "operator": "or"
      }
    }
  }
}

search wor,被分词为 search, wor
要求文档中出现 search 或者 有关键字是以 wor 开头。
operator 还有 and 选项。即文档中必须有 search 关键字, 且有关键字以 wor 开头。

Match phrase query

短语搜索。将搜索词分词,而后根据 slop 定义的词与词的间距,判断词与词之间最多能出现多少单词

GET /test/_search
{
  "query": {
    "match_phrase": {
      "name": {
        "query": "hello elasticsearch",
        "slop": 2
      }
    }
  }
}

hello elasticsearch 被分词为 hello, elasticsearch
slop=2 表示匹配的文档, hello, elasticsearch 之间至多只能间隔 2 个词。

Match phrase prefix query

短语搜索和前缀搜索的结合体。

GET /test/_search
{
  "query": {
    "match_phrase_prefix": {
      "name": {
        "query": "you sear",
        "slop": 2
      }
    }
  }
}

you sear 被分词为 you, sear
slop=2 表示匹配的文档, you, sear 之间至多只能间隔 2 个词。并且只要以 sear 开头即满足条件。

Combined fields

组合查询。需要注意的是,被搜索的字段,需要有相同的分词器。

PUT /test2/_doc/1
{
  "name": "elasticsearch i love it",
  "title": "java is very good"
}
PUT /test2/_doc/2
{
  "name": "php i love it",
  "title": "mysql is very good"
}
PUT /test2/_doc/3
{
  "name": "redis i love it",
  "title": "rocketMQ is very good"
}

GET /test2/_search
{
  "query": {
     "combined_fields" : {
      "query":      "java redis",
      "fields":     [ "name", "title"],
      "operator":   "or"
    }
  }
}

java redis 分词为 java、redis, 并在 name、title 中查找。name 或者 title 中有出现,文档就算匹配。

Multi-match query

多字段查询。

GET /test2/_search
{
  "query": {
    "multi_match": {
      "query": "mysql java",
      "fields": ["name", "title"]
    }
  }
}

mysql java 分词为 mysql, java。分别在 name, title 中查询,如果 name 或者 title 中有匹配,文档就算匹配。
评分公式为:max(field_scores) * boost

type

type 会影响查询的行为和结果

best_fields

默认 type 为 best_fields。

假设:

字段 文档 ID mysql 得分 java 得分 最终得分
name 1 0 3 0 + 3
title 1 7 0 7 + 0
文档 1 最终得分 max(3, 7) = 7
most_fields
GET /test2/_search
{
  "query": {
    "multi_match": {
      "query": "mysql java",
      "fields": ["name", "title"],
      "type": "most_fields"
    }
  }
}

与 best_fields 的区别为:算分公式为,sum(field_scores * boost)

字段 文档 ID mysql 得分 java 得分 最终得分
name 1 0 10 0 + 10
title 1 10 0 10 + 0
文档 1 最终得分 10 + 10
cross_fields
GET /test2/_search
{
  "query": {
    "multi_match": {
      "query": "php java",
      "fields": ["name", "title"],
      "type": "cross_fields"
    }
  }
}

算分公式为, sum(max( term_in_field_scores * boost))。即 每个分词(term) 在不同 field 中得分最大值之和,即为该文档的得分。

与 most_fields, best_fields 主要区别在于,cross_fields 算分是以 term(分词) 为纬度,后两者是以字段为维度。

分词(term) 文档 ID name 中的得分 title 中的得分 最终得分
php 1 12 10 12(取最大的)
java 1 3 10 10(取最大的)
文档 1 最终得分 (12) + (10)
phrase, phrase_prefix

与 Match boolean prefix query、Match phrase query 类似。只不过是在多个字段中搜索,不过多介绍

tie_breaker

tie_breaker 是一个 0-1 的值。默认为 0.
当设置了 tie_breaker 后,算分公式会变为。
final_score = max_score + tie_breaker * sum_of_other_scores
即,tie_breaker 值越大,其他字段的得分对总得分影响越大。

我们以 cross_fields 举例说明。

GET /test2/_search
{
  "query": {
    "multi_match": {
      "query": "php java",
      "fields": ["name", "title"],
      "type": "cross_fields"
    }
  }
}
分词(term) 文档 ID name 中的得分 title 中的得分 最终得分 tie_breaker = 0.3 时的得分
php 1 12 10 12(取最大的) 12 + 10 * 0.3
java 1 3 10 10(取最大的) 10 + 3 * 0.3
文档 1 最终得分 (12 + 10 * 0.3) + (10 + 3 * 0.3)
operator

默认为 or

例如

GET /test2/_search
{
  "query": {
    "multi_match": {
      "query": "mysql java",
      "fields": ["name", "title"],
      "operator": "or"
    }
  }
}

表示,(mysql, java) in name or (mysql, java) in title
即只要有 1个 term 存在于 field 就算匹配。

还有另外一个值 and
例如

GET /test2/_search
{
  "query": {
    "multi_match": {
      "query": "mysql java",
      "fields": ["name", "title"],
      "operator": "and"
    }
  }
}

表示,((mysql) in name and (java) in name) OR ((mysql) in title and (java) in title)
即 terms 必须同时出现在 field 才算匹配。

boost

我们可以为每个字段单独设置权重。
例如

GET /test2/_search
{
  "query": {
    "multi_match": {
      "query": "mysql java",
      "fields": ["name^2", "title^3"],
      "operator": "and"
    }
  }
}

name^2, 表示,在对 name 字段进行算法时,需要将得分 * 2。

{
  "query": {  
    "intervals": {  
     "name": {   
     "all_of": {  
   "ordered": true,  
  "intervals": [  
 { "match": { "query": "am" }},  
 { "match": { "query": "i" }},  
 { "match": { "query": "java" }}  
   ]  
        }  
      }  
    }  
  }  
}  

你可能感兴趣的:(Elasticsearch,elasticsearch)