搜索从得分上来说可以分为 2 类,需要搜索得分和不需要搜索得分。
搜索得分可以看做是匹配度的高低,对于“固定值”的搜索而言,通常不需要计算得分。其好处可以进行缓存,同时减轻服务器计算压力。
本章内容就是讲述固定值的搜索:Term 查询
Term 查询通常用于:Keyword 关键字,Bool 类型,Date日期类型、Number 数值类型等的查询

数据准备

按照流程:创建索引、新建映射、插入文档数据的步骤进行

  1. # 删除之前的索引
  2. DELETE /article
  3. # 重建索引
  4. PUT /article
  5. # 设置映射
  6. PUT /article/_mapping
  7. {
  8. "properties": {
  9. "articleID": {
  10. "type": "keyword"
  11. }
  12. }
  13. }
  14. # 查看映射
  15. GET /article/_mapping
  16. # 批量添加数据
  17. POST article/_bulk
  18. { "index": { "_id": 1 }}
  19. { "articleID" : "XHDK-A-1293-#fJ3", "userID" : 1, "hidden": false, "postDate": "2017-01-01"}
  20. { "index": { "_id": 2 }}
  21. { "articleID" : "KDKE-B-9947-#kL5", "userID" : 1, "hidden": false, "postDate": "2017-01-04" }
  22. { "index": { "_id": 3 }}
  23. { "articleID" : "JODL-X-1937-#pV7", "userID" : 2, "hidden": false, "postDate": "2017-05-01"}
  24. { "index": { "_id": 4 }}
  25. { "articleID" : "QQPX-R-3956-#aD8", "userID" : 2, "hidden": true, "postDate": "2017-03-02" }

通过上述操作后,可以通过如下形式进行检索

  1. GET /article/_search
  2. {
  3. "query": {
  4. "match_all": {}
  5. },
  6. "from": 0,
  7. "size": 50
  8. }

单字段匹配

上述代码中我们仅仅手动设置了 articleIDkeyword ,所以可以可以通过获取 Mapping 来确定当前文档的定义。

  1. GET /article/_mapping

结果是

  1. {
  2. "article" : {
  3. "mappings" : {
  4. "properties" : {
  5. "articleID" : {
  6. "type" : "keyword"
  7. },
  8. "hidden" : {
  9. "type" : "boolean"
  10. },
  11. "postDate" : {
  12. "type" : "date"
  13. },
  14. "userID" : {
  15. "type" : "long"
  16. }
  17. }
  18. }
  19. }
  20. }

可以看出字段的类型为:keyword/boolean/date/long 这些类型都是可以通过 term 进行查询的。
首先来一个简答的根据 userID 进行查询

  1. GET /article/_search
  2. {
  3. "query": {
  4. "constant_score": {
  5. "filter": {
  6. "term": {
  7. "userID": "2"
  8. }
  9. }
  10. }
  11. }
  12. }

大体结构是:query -> constant_score -> filter -> term -> filed
同理 Term 支持 当前这个文档每个字段的查询

  1. GET /article/_search
  2. {"query":{"constant_score":{"filter":{"term":{"postDate":"2017-01-02"}}}}}

其他类似,不做赘述。

Term查询只希望对文档进行包括或排除的计算,所以我们会使用 constant_score 查询以非评分模式来执行 term 查询并以一作为统一评分。因为在查询时,不需要计算评分,因此采用constant_score寻找的方式速度会更快。 如果一个查询只有filter过滤条件,可以用constant_score来替代bool查询,这样的查询语句更简洁、更清晰,只是没有评分。

多字段匹配

  1. GET /article/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "filter": [ #此处 filter 也可以改为 must,案例3
  6. {
  7. "term": {
  8. "userID": "1"
  9. }
  10. },
  11. {
  12. "term": {
  13. "postDate": "2017-01-02"
  14. }
  15. }
  16. ]
  17. }
  18. }
  19. }

以下这个写法是错误的,会提示:"[term] query doesn't support multiple fields, found [userID] and [postDate]"

  1. GET /article/_search
  2. {
  3. "query": {
  4. "constant_score": {
  5. "filter": {
  6. "term": {
  7. "userID": "1",
  8. "postDate": "2017-01-02"
  9. }
  10. }
  11. }
  12. }
  13. }

感觉下面的理解更好:query -> bool -> must

  1. GET /article/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "term": {
  8. "userID": "1"
  9. }
  10. },
  11. {
  12. "term": {
  13. "postDate": "2017-01-02"
  14. }
  15. }
  16. ]
  17. }
  18. }
  19. }

bool 查询中 filtered 的用法已经被淘汰,推荐更换为 bool 用法。

单字段 In

  1. GET /article/_search
  2. {
  3. "query": {
  4. "terms": {
  5. "postDate": ["2017-01-01","2017-01-02"]
  6. }
  7. }
  8. }
  9. GET /article/_search
  10. {
  11. "query": {
  12. "constant_score": {
  13. "filter": {
  14. "terms": {
  15. "postDate": ["2017-01-01","2017-01-02"]
  16. }
  17. }
  18. }
  19. }
  20. }

对于 terms 这样的等值匹配,感觉使用 constant_score + filter是没有效果的,上述案例的写法 1写法 2 效果相同。