elasticsearch-mathc和term的区分

elasticsearch和mysql在思想上是有不一样的,elasticsearch有分词一说,好比北京奥运分词成北京奥运北京奥运。分词要要考虑两点,一个是查询字符串要不要分词,还有就是原存储字段是否是精确值。mysql

1. match 查询

不管你在任何字段上进行的是全文搜索仍是精确查询,match 查询是你可用的标准查询。sql

`、若是你在一个全文字段上使用 match 查询,在执行查询前,它将用正确的分析器去分析查询字符串:curl

{ "match": { "tweet": "About Search" }}

二、若是在一个精确值的字段上使用它, 例如数字、日期、布尔或者一个 NOT_ANALYZED 字符串字段,那么它将会精确匹配给定的值:elasticsearch

{ "match": { "age":    26           }}
{ "match": { "date":   "2014-09-01" }}
{ "match": { "public": true         }}
{ "match": { "tag":    "full_text"  }}

match查询会先对搜索词进行分词,分词完毕后再逐个对分词结果进行匹配,所以相比于term的精确搜索,match是分词匹配搜索,match搜索还有两个类似功能的变种,一个是match_phrase,一个是multi_matchurl

2. term 查询

term是表明彻底匹配,也就是精确查询,搜索前不会再对搜索词进行分词,因此咱们的搜索词必须是文档分词集合中的一个。好比说咱们要找标题为北京奥运的全部文档spa

$curl -XGET http://localhost:9200/index/doc/_search?pretty -d 
'{
  "query":{
    "term":{
        "title":"北京奥运"
    }
  }
}'

将会获得以下结果code

{
    "took": 1,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
    "total": 1,
    "max_score": 0.92055845,
    "hits": [
     {
        "_index": "index",
        "_type": "doc",
        "_id": "3",
        "_score": 0.92055845,
        "_source": {
           "content": "同一个世界同一个梦想",
           "title": "北京奥运",
           "tags": [
               "和平"
            ]
        }
      }
    ]
  }
}

搜索title包含北京或者奥运的,结果也同样,可是若是你搜索词为京奥,或者北京奥这样的,那么搜索结果将为空索引

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
      "total" : 5,
      "successful" : 5,
      "failed" : 0
  },
  "hits" : {
      "total" : 0,
      "max_score" : null,
      "hits" : [ ]
  }
}

3. match_phrase

match_phrase为按短语搜索,match_phrase的搜索方式和match相似,先对搜索词创建索引,并要求全部分词必须在文档中出现(像不像operator为and的match查询),除此以外,还必须知足分词在文档中出现的顺序和搜索词中一致且各搜索词之间必须紧邻,所以match_phrase也能够叫作紧邻搜索。文档

因此,当咱们搜美国留给字符串

curl -XGET http://localhost:9200/index/doc/_search?pretty -d 
'{
  "query": {
    "match_phrase": {
        "content": "美国留给"
    }
  }
}'

如下内容美国留给伊拉克的是个烂摊子吗是能够搜索出来的

"_source" : {
        "content" : "美国留给伊拉克的是个烂摊子吗",
        "title" : "标题",
        "tags" : [ "美国", "伊拉克", "烂摊子" ]
    }

可是咱们搜索留给美国美国伊拉克时,却没有搜索结果,由于第一个顺序不对,第二个不是紧邻(隔着留给)。

紧邻对于匹配度要求较高,为了减少精度增长可操做性,引入了slop参数。该参数能够指定相隔多少个词仍被算做匹配成功。以下,

curl -XGET http://localhost:9200/index/doc/_search?pretty -d 
'{
    "query": {
        "match_phrase": {
            "content": {
                "query": "美国伊拉克",
                "slop": "1"
            }
        }
    }
}'

当咱们将slop设置为1时,下面文档是能够搜索到的

"_source" : {
    "content" : "美国留给伊拉克的是个烂摊子吗",
    "title" : "标题",
    "tags" : [ "美国", "伊拉克", "烂摊子" ]
  }

须要注意的是,当slop的值过大时(超出文档总分词数),那么分词数据将能够是随意的,即跟operator为and的match查询效果同样。好比咱们查询

curl -XGET http://localhost:9200/index/doc/_search?pretty -d 
'{
    "query": {
        "match_phrase": {
            "content": {
                "query": "伊拉克美国",
                "slop": "12"
            }
        }
    }
}'

将会获得与上面同样的结果

4. multi_match

若是咱们但愿两个字段进行匹配,其中一个字段有这个文档就知足的话,使用multi_match

{
  "query": {
    "multi_match": {
        "query" : "个人宝马多少马力",
        "fields" : ["title", "content"]
    }
  }
}

可是multi_match就涉及到匹配评分的问题了。