ElasticSearch扫盲之十一:ElasticSearch结构化查询语句Query DSL之组合查询即bool查询

组合条件查询是基于叶子查询条件,将叶子条件作为子条件,形成一个多字段多条件的组合条件.

一、bool条件

1.功能及参数
  • 功能:通过多个叶子条件形成一个bool条件树
  • 参数:
    • must : 必须满足指定的条件(各子条件是AND关系)
    • filter : 指定必须满足的条件(不统计相关度评分)
    • should : 满足一个子条件即可(各子条件是OR关系)
    • must_not : 不满足条件(NOT)

must/filter/shoud/must_not 等的子条件是通过 term/terms/range/ids/exists/match 等叶子条件为参数的

注:以上参数,当只有一个搜索条件时,must等对应的是一个对象,当是多个条件时,对应的是一个数组

2.must

通过must来查询状态为1的用户列表

  1. GET user/_doc/_search
  2. {
  3. "_source":["user_id", "status"],
  4. "query":{
  5. "bool":{
  6. "must":{
  7. "term":{
  8. "status":1
  9. }
  10. }
  11. }
  12. }
  13. }

查询结果:

  1. {
  2. "took" : 2,
  3. "timed_out" : false,
  4. "_shards" : {
  5. "total" : 5,
  6. "successful" : 5,
  7. "skipped" : 0,
  8. "failed" : 0
  9. },
  10. "hits" : {
  11. "total" : 4,
  12. "max_score" : 1.0,
  13. "hits" : [
  14. {
  15. "_index" : "user",
  16. "_type" : "_doc",
  17. "_id" : "5",
  18. "_score" : 1.0,
  19. "_source" : {
  20. "user_id" : 5,
  21. "status" : 1
  22. }
  23. },
  24. {
  25. "_index" : "user",
  26. "_type" : "_doc",
  27. "_id" : "4",
  28. "_score" : 1.0,
  29. "_source" : {
  30. "user_id" : 4,
  31. "status" : 1
  32. }
  33. },
  34. {
  35. "_index" : "user",
  36. "_type" : "_doc",
  37. "_id" : "6",
  38. "_score" : 1.0,
  39. "_source" : {
  40. "user_id" : 6,
  41. "status" : 1
  42. }
  43. },
  44. {
  45. "_index" : "user",
  46. "_type" : "_doc",
  47. "_id" : "1",
  48. "_score" : 1.0,
  49. "_source" : {
  50. "user_id" : 1,
  51. "status" : 1
  52. }
  53. }
  54. ]
  55. }
  56. }
3.filter

filter与其他子查询条件不同,它不计算_score即相关度评分,效率更高

  1. GET user/_doc/_search
  2. {
  3. "_source":["user_id", "status"],
  4. "query":{
  5. "bool":{
  6. "filter":{
  7. "term":{
  8. "status":1
  9. }
  10. }
  11. }
  12. }
  13. }

查询结果:

  1. {
  2. "took" : 4,
  3. "timed_out" : false,
  4. "_shards" : {
  5. "total" : 5,
  6. "successful" : 5,
  7. "skipped" : 0,
  8. "failed" : 0
  9. },
  10. "hits" : {
  11. "total" : 4,
  12. "max_score" : 0.0,
  13. "hits" : [
  14. {
  15. "_index" : "user",
  16. "_type" : "_doc",
  17. "_id" : "5",
  18. "_score" : 0.0,
  19. "_source" : {
  20. "user_id" : 5,
  21. "status" : 1
  22. }
  23. },
  24. {
  25. "_index" : "user",
  26. "_type" : "_doc",
  27. "_id" : "4",
  28. "_score" : 0.0,
  29. "_source" : {
  30. "user_id" : 4,
  31. "status" : 1
  32. }
  33. },
  34. {
  35. "_index" : "user",
  36. "_type" : "_doc",
  37. "_id" : "6",
  38. "_score" : 0.0,
  39. "_source" : {
  40. "user_id" : 6,
  41. "status" : 1
  42. }
  43. },
  44. {
  45. "_index" : "user",
  46. "_type" : "_doc",
  47. "_id" : "1",
  48. "_score" : 0.0,
  49. "_source" : {
  50. "user_id" : 1,
  51. "status" : 1
  52. }
  53. }
  54. ]
  55. }
  56. }

通过结果的_score字段可以看出,没有计算_score的值

4.should

当多个条件之间是OR的关系时,使用should

如查询address中包含”zhejiang”或”nickname”为”shixinke”的记录

  1. GET user/_doc/_search
  2. {
  3. "_source": [
  4. "user_id",
  5. "nickname",
  6. "address"
  7. ],
  8. "query": {
  9. "bool": {
  10. "should": [
  11. {
  12. "match": {
  13. "address": "zhejiang"
  14. }
  15. },
  16. {
  17. "term":{
  18. "nickname":"shixinke"
  19. }
  20. }
  21. ]
  22. }
  23. }
  24. }

查询结果:

  1. {
  2. "took" : 4,
  3. "timed_out" : false,
  4. "_shards" : {
  5. "total" : 5,
  6. "successful" : 5,
  7. "skipped" : 0,
  8. "failed" : 0
  9. },
  10. "hits" : {
  11. "total" : 2,
  12. "max_score" : 0.5753642,
  13. "hits" : [
  14. {
  15. "_index" : "user",
  16. "_type" : "_doc",
  17. "_id" : "1",
  18. "_score" : 0.5753642,
  19. "_source" : {
  20. "address" : "HangZhou,ZheJiang,China",
  21. "user_id" : 1,
  22. "nickname" : "shixinke"
  23. }
  24. },
  25. {
  26. "_index" : "user",
  27. "_type" : "_doc",
  28. "_id" : "5",
  29. "_score" : 0.2876821,
  30. "_source" : {
  31. "address" : "NingBo,ZheJiang,China",
  32. "user_id" : 5,
  33. "nickname" : "jet"
  34. }
  35. }
  36. ]
  37. }
  38. }
5.must_not

must_not用于排除某个条件的记录

如:查询状态不为0的用户列表

  1. GET user/_doc/_search
  2. {
  3. "_source": [
  4. "user_id",
  5. "status"
  6. ],
  7. "query": {
  8. "bool":{
  9. "must_not":{
  10. "term":{
  11. "status":0
  12. }
  13. }
  14. }
  15. }
  16. }

查询结果:

  1. {
  2. "took" : 2,
  3. "timed_out" : false,
  4. "_shards" : {
  5. "total" : 5,
  6. "successful" : 5,
  7. "skipped" : 0,
  8. "failed" : 0
  9. },
  10. "hits" : {
  11. "total" : 4,
  12. "max_score" : 1.0,
  13. "hits" : [
  14. {
  15. "_index" : "user",
  16. "_type" : "_doc",
  17. "_id" : "5",
  18. "_score" : 1.0,
  19. "_source" : {
  20. "user_id" : 5,
  21. "status" : 1
  22. }
  23. },
  24. {
  25. "_index" : "user",
  26. "_type" : "_doc",
  27. "_id" : "4",
  28. "_score" : 1.0,
  29. "_source" : {
  30. "user_id" : 4,
  31. "status" : 1
  32. }
  33. },
  34. {
  35. "_index" : "user",
  36. "_type" : "_doc",
  37. "_id" : "6",
  38. "_score" : 1.0,
  39. "_source" : {
  40. "user_id" : 6,
  41. "status" : 1
  42. }
  43. },
  44. {
  45. "_index" : "user",
  46. "_type" : "_doc",
  47. "_id" : "1",
  48. "_score" : 1.0,
  49. "_source" : {
  50. "user_id" : 1,
  51. "status" : 1
  52. }
  53. }
  54. ]
  55. }
  56. }

二、constant_score

给每条记录以一条固定的评分,即不计算相关度评分,所能constant_score只支持filter上下文

  1. GET user/_doc/_search
  2. {
  3. "_source": [
  4. "user_id",
  5. "status"
  6. ],
  7. "query": {
  8. "constant_score":{
  9. "filter":{
  10. "term":{
  11. "status":1
  12. }
  13. }
  14. }
  15. }
  16. }

查询结果:

  1. {
  2. "took" : 1,
  3. "timed_out" : false,
  4. "_shards" : {
  5. "total" : 5,
  6. "successful" : 5,
  7. "skipped" : 0,
  8. "failed" : 0
  9. },
  10. "hits" : {
  11. "total" : 4,
  12. "max_score" : 1.0,
  13. "hits" : [
  14. {
  15. "_index" : "user",
  16. "_type" : "_doc",
  17. "_id" : "5",
  18. "_score" : 1.0,
  19. "_source" : {
  20. "user_id" : 5,
  21. "status" : 1
  22. }
  23. },
  24. {
  25. "_index" : "user",
  26. "_type" : "_doc",
  27. "_id" : "4",
  28. "_score" : 1.0,
  29. "_source" : {
  30. "user_id" : 4,
  31. "status" : 1
  32. }
  33. },
  34. {
  35. "_index" : "user",
  36. "_type" : "_doc",
  37. "_id" : "6",
  38. "_score" : 1.0,
  39. "_source" : {
  40. "user_id" : 6,
  41. "status" : 1
  42. }
  43. },
  44. {
  45. "_index" : "user",
  46. "_type" : "_doc",
  47. "_id" : "1",
  48. "_score" : 1.0,
  49. "_source" : {
  50. "user_id" : 1,
  51. "status" : 1
  52. }
  53. }
  54. ]
  55. }
  56. }

从结果可以看出_score是一个固定的值”1.0”

三、dis_max

在多字段全文检索时,固定相关度评分,即不计算相关度评分,而不是尽可能多的field匹配了少数的关键词(取分数最高的那个字段的分数)

如下:查询status为1或address中包含zhejiang的记录,有的记录匹配status=1,有的记录匹配addres包含zhejiang,这时取最匹配的那个字段的分数

  1. GET user/_doc/_search
  2. {
  3. "_source": [
  4. "user_id",
  5. "address"
  6. ],
  7. "query": {
  8. "dis_max": {
  9. "queries": [
  10. {
  11. "term": {
  12. "status": 1
  13. }
  14. },
  15. {
  16. "match":{
  17. "address":"zhejiang"
  18. }
  19. }
  20. ]
  21. }
  22. }
  23. }

查询结果:

  1. {
  2. "took" : 1,
  3. "timed_out" : false,
  4. "_shards" : {
  5. "total" : 5,
  6. "successful" : 5,
  7. "skipped" : 0,
  8. "failed" : 0
  9. },
  10. "hits" : {
  11. "total" : 4,
  12. "max_score" : 1.0,
  13. "hits" : [
  14. {
  15. "_index" : "user",
  16. "_type" : "_doc",
  17. "_id" : "5",
  18. "_score" : 1.0,
  19. "_source" : {
  20. "address" : "NingBo,ZheJiang,China",
  21. "user_id" : 5
  22. }
  23. },
  24. {
  25. "_index" : "user",
  26. "_type" : "_doc",
  27. "_id" : "4",
  28. "_score" : 1.0,
  29. "_source" : {
  30. "address" : "PuDong,ShangHai,China",
  31. "user_id" : 4
  32. }
  33. },
  34. {
  35. "_index" : "user",
  36. "_type" : "_doc",
  37. "_id" : "6",
  38. "_score" : 1.0,
  39. "_source" : {
  40. "address" : "SuZhou,JiangSu,China",
  41. "user_id" : 6
  42. }
  43. },
  44. {
  45. "_index" : "user",
  46. "_type" : "_doc",
  47. "_id" : "1",
  48. "_score" : 1.0,
  49. "_source" : {
  50. "address" : "HangZhou,ZheJiang,China",
  51. "user_id" : 1
  52. }
  53. }
  54. ]
  55. }
  56. }