term查询
    
   
Term 是表达语意的最⼩单位。搜索和利⽤统计语⾔模型进⾏⾃然语⾔处理都需要处理 Term
term查询分为:
Term Level Query: Term Query / Range Query / Exists Query / Prefix Query /Wildcard Query
    ES 中,Term 查询,对输⼊不做分词。会将输⼊作为⼀个整体,在倒排索引中查找准确的词项,并
    
    且使⽤相关度算分公式为每个包含该词项的⽂档进⾏相关度算分 – 例如“Apple Store”
   
    POST /products/_bulk
    
    { “index”: { “_id”: 1 }}
    
    { “productID” : “XHDK-A-1293-#fJ3″,”desc”:”iPhone” }
    
    { “index”: { “_id”: 2 }}
    
    { “productID” : “KDKE-B-9947-#kL5″,”desc”:”iPad” }
    
    { “index”: { “_id”: 3 }}
    
    { “productID” : “JODL-X-1937-#pV7″,”desc”:”MBP” }
   
GET /products
    POST /products/_search
    
    {
    
    
    “query”: {
    
    
    “term”: {
    
    
    “desc”: {
    
    
    //”value”: “iPhone”
    
    “value”:”iphone”
    
    }
    
    }
    
    }
    
    }
   
    POST /products/_search
    
    {
    
    
    “query”: {
    
    
    “term”: {
    
    
    “desc.keyword”: {
    
    
    //”value”: “iPhone”
    
    //”value”:”iphone”
    
    }
    
    }
    
    }
    
    }
   
    
    POST /products/_search
    
    {
    
    
    “query”: {
    
    
    “term”: {
    
    
    “productID”: {
    
    
    “value”: “XHDK-A-1293-#fJ3”
    
    }
    
    }
    
    }
    
    }
   
    POST /products/_search
    
    {
    
    
    //”explain”: true,
    
    “query”: {
    
    
    “term”: {
    
    
    “productID.keyword”: {
    
    
    “value”: “XHDK-A-1293-#fJ3”
    
    }
    
    }
    
    }
    
    }
   
    如果字段设置了keyword,你用term查询,就会精确匹配。例如说keyword字段,索引时是“Iphone”,你的term查询必须是Iphone,输入“iphone”就无法匹配。
    
    而如果你的字段是“text”类型。你index时候,如果是“Iphone”,在term查询时,“iphone”可以匹配。但是,“Iphone”不会。很多刚接触的同学会有点困惑。背后的原因是,text类型的数据会分词,默认分词器会将输入一个个单词切开,并且转小写了。所以你 term查询时,必须用“iphone”
    
    如果你是match查询,在text字段上查询iphone或者Iphone 应该都能查到。
   
date类型是包含时区信息的,如果我们没有在json代表日期的字符串中显式指定时区,对es来说没什么问题,
但是如果通过kibana显示es里的数据时,就会出现问题,数据的时间会晚8个小时。因为kibana从es里读取的date类型数据,没有时区信息,
    kibana会默认当作0时区来解析,但是kibana在通过浏览器展示的时候,会通过js获取当前客户端机器所在的时区,也就是东八区,
    
    所以kibana会把从es得到的日期数据减去8小时。这里就会导致kibana经常遇到的“数据时间延迟8小时”的问题。
    
    所以最佳实践方案就是:我们在往es提交日期数据的时候,直接提交带有时区信息的日期字符串,如:“2016-07-15T12:58:17.136+0800”。
    
    ##索引中定义的日期格式与提交数据的日期格式要一致,否则会报错
   
    
     可以通过 Constant Score 将查询转换成⼀个 Filtering,避免算分,并利⽤缓存,提⾼性能
    
   
    POST /products/_search
    
    {
    
    
    “explain”: true,
    
    “query”: {
    
    
    “constant_score”: {
    
    
    “filter”: {
    
    
    “term”: {
    
    
    “productID.keyword”: “XHDK-A-1293-#fJ3”
    
    }
    
    }
   
    }
    
    }
    
    }
   
默认算分都为1
{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_shard" : "[products][0]",
        "_node" : "FOnISXrCSHCxo6YKkUhf7g",
        "_index" : "products",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "productID" : "XHDK-A-1293-#fJ3",
          "desc" : "iPhone"
        },
        "_explanation" : {
          "value" : 1.0,
          "description" : "ConstantScore(productID.keyword:XHDK-A-1293-#fJ3)",
          "details" : [ ]
        }
      }
    ]
  }
}
    
     基于全⽂的查询
    
    
    基于全⽂本的查找有:
    
    Match Query / Match Phrase Query / Query String Query
    
    特点:
    
    索引和搜索时都会进⾏分词,查询字符串先传递到⼀个合适的分词器,然后⽣成⼀个供查询的词
    
    项列表
    
    查询时候,先会对输⼊的查询进⾏分词,然后每个词项逐个进⾏底层的查询,最终将结果进⾏合
    
    并。并为每个⽂档⽣成⼀个算分。- 例如查 “Matrix reloaded”,会查到包括 Matrix 或者 reload
    
    的所有结果
   
    POST /movies/_search
    
    {
    
    
    “query”: {
    
    
    “match”: {
    
    
    “title”:{
    
    
    “query”: “Matrix reloaded”
    
    }
    
    }
    
    }
    
    }
   
{
  "took" : 19,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 16.501785,
    "hits" : [
      {
        "_index" : "movies",
        "_type" : "_doc",
        "_id" : "6365",
        "_score" : 16.501785,
        "_source" : {
          "genre" : [
            "Action",
            "Adventure",
            "Sci-Fi",
            "Thriller",
            "IMAX"
          ],
          "title" : "Matrix Reloaded, The",
          "@version" : "1",
          "id" : "6365",
          "year" : 2003
        }
      },
      {
        "_index" : "movies",
        "_type" : "_doc",
        "_id" : "2571",
        "_score" : 9.095142,
        "_source" : {
          "genre" : [
            "Action",
            "Sci-Fi",
            "Thriller"
          ],
          "title" : "Matrix, The",
          "@version" : "1",
          "id" : "2571",
          "year" : 1999
        }
      },
      {
        "_index" : "movies",
        "_type" : "_doc",
        "_id" : "6934",
        "_score" : 7.832533,
        "_source" : {
          "genre" : [
            "Action",
            "Adventure",
            "Sci-Fi",
            "Thriller",
            "IMAX"
          ],
          "title" : "Matrix Revolutions, The",
          "@version" : "1",
          "id" : "6934",
          "year" : 2003
        }
      }
    ]
  }
}
返回结果包含Matrix 或者 reloaded
想要两者都包含:
    方法1:POST /movies/_search
    
    {
    
    
    “query”: {
    
    
    “match”: {
    
    
    “title”:{
    
    
    “query”: “Matrix reloaded”,
    
    “operator”: “AND”
    
    }
    
    }
    
    }
    
    }
   
    方法2:POST /movies/_search
    
    {
    
    
    “query”: {
    
    
    “match”: {
    
    
    “title”:{
    
    
    “query”: “Matrix reloaded”,
    
    “minimum_should_match”: 2
    
    }
    
    }
    
    }
    
    }
   
minimum_should_match ,最小匹配度
    方法3:POST /movies/_search
    
    {
    
    
    “query”: {
    
    
    “match_phrase”: {
    
    
    “title”:{
    
    
    “query”: “Matrix reloaded”,
    
    “slop”: 1
    
    }
    
    }
    
    }
    
    }
   
    
     position_increment_gap
    
    设置告诉 Elasticsearch 应该为数组中每个新元素增加当前词条
    
     position
    
    的指定值。
   
    PUT groups
    
    {
    
    
    “mappings”: {
    
    
    “properties”: {
    
    
    “names”:{
    
    
    “type”: “text”,
    
    “position_increment_gap”: 0
    
    }
    
    }
    
    }
    
    }
    
    GET groups/_mapping
    
    GET groups/_search
    
    POST groups/_doc
    
    {
    
    
    “names”: [ “John Water”, “Water Smith”]
    
    }
   
    POST groups/_search
    
    {
    
    
    “query”: {
    
    
    “match_phrase”: {
    
    
    “names”: {
    
    
    “query”: “Water Water”,
    
    “slop”: 100
    
    }
    
    }
    
    }
    
    }
   
    
    POST groups/_search
    
    {
    
    
    “query”: {
    
    
    “match_phrase”: {
    
    
    “names”: “Water Smith”
    
    }
    
    }
    
    }
   
 
