
搜索从得分上来说可以分为 2 类,需要搜索得分和不需要搜索得分。
搜索得分可以看做是匹配度的高低,对于“固定值”的搜索而言,通常不需要计算得分。其好处可以进行缓存,同时减轻服务器计算压力。
本章内容就是讲述固定值的搜索:Term 查询、范围 Range 查询、空值判定 Exists、
Term 查询通常用于:Keyword 关键字,Bool 类型,Date日期类型、Number 数值类型等的查询
按照流程:创建索引、新建映射、插入文档数据的步骤进行
# 删除之前的索引
DELETE /article
# 重建索引
PUT /article
# 设置映射
PUT /article/_mapping
{
  "properties": {
    "articleID": {
      "type": "keyword"
    }
  }
}
# 查看映射
GET /article/_mapping
# 批量添加数据
POST article/_bulk
{ "index": { "_id": 1 }}
{ "articleID" : "XHDK-A-1293-#fJ3", "userID" : 1, "hidden": false, "postDate": "2017-01-01"}
{ "index": { "_id": 2 }}
{ "articleID" : "KDKE-B-9947-#kL5", "userID" : 1, "hidden": false, "postDate": "2017-01-04" }
{ "index": { "_id": 3 }}
{ "articleID" : "JODL-X-1937-#pV7", "userID" : 2, "hidden": false, "postDate": "2017-05-01"}
{ "index": { "_id": 4 }}
{ "articleID" : "QQPX-R-3956-#aD8", "userID" : 2, "hidden": true, "postDate": "2017-03-02" }
通过上述操作后,可以通过如下形式查询所有的结果来检验下数据是否插入进去。
GET /article/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 50
}
以下是一组2 种 term 的通用等价写法,其中avaliable是一个bool类型的字段。

上述代码中我们仅仅手动设置了 articleID 为 keyword ,所以可以可以通过获取 Mapping 来确定当前文档的定义。
GET /article/_mapping
结果是
{
  "article" : {
    "mappings" : {
      "properties" : {
        "articleID" : {
          "type" : "keyword"
        },
        "hidden" : {
          "type" : "boolean"
        },
        "postDate" : {
          "type" : "date"
        },
        "userID" : {
          "type" : "long"
        }
      }
    }
  }
}
可以看出字段的类型为:keyword/boolean/date/long 这些类型都是可以通过 term 进行查询的。
首先来一个简答的根据 userID 进行查询
GET /article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "userID": "2"
        }
      }
    }
  }
}
大体结构是:query -> constant_score -> filter -> term -> filed
同理 Term 支持 当前这个文档每个字段的查询
GET /article/_search
{"query":{"constant_score":{"filter":{"term":{"postDate":"2017-01-02"}}}}}
其他类似,不做赘述。
Term查询只希望对文档进行包括或排除的计算,所以我们会使用 constant_score 查询以非评分模式来执行 term 查询并以一作为统一评分。因为在查询时,不需要计算评分,因此采用constant_score寻找的方式速度会更快。
如果一个查询只有filter过滤条件,可以用constant_score来替代bool查询,这样的查询语句更简洁、更清晰,只是没有评分。
GET /article/_search
{
  "query": {
    "bool": {
      "filter": [ #此处 filter 也可以改为 must,案例3
        {
          "term": {
            "userID": "1"
          }
        },
        {
          "term": {
            "postDate": "2017-01-02"
          }
        }
      ]
    }
  }
}
以下这个写法是错误的,会提示:"[term] query doesn't support multiple fields, found [userID] and [postDate]"。
GET /article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "userID": "1",
          "postDate": "2017-01-02"
        }
      }
    }
  }
}
感觉下面的理解更好:query -> bool -> must
GET /article/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "userID": "1"
          }
        },
        {
          "term": {
            "postDate": "2017-01-02"
          }
        }
      ]
    }
  }
}
bool 查询中 filtered 的用法已经被淘汰,推荐更换为 bool 用法。
GET /article/_search
{
  "query": {
    "terms": {
      "postDate": ["2017-01-01","2017-01-02"]
    }
  }
}
GET /article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "terms": {
            "postDate": ["2017-01-01","2017-01-02"]
        }
      }
    }
  }
}
对于 terms 这样的等值匹配,感觉使用 constant_score + filter 是没有效果的,上述案例的写法 1 和写法 2 效果相同。
GET /article/_search
{
  "query": {
    "range": {
      "postDate": {
        "gte":"2017-01-01",
        "lt": "2018-01-01"
      }
    }
  }
}
可以理解为 SQL中的 where postDate is not null
GET /article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "exists": {
          "field": "postDate"
        }
      }
    }
  }
}