查询数据

简单聚合

比如我们希望计算出account每个州的统计数量, 使用aggs关键字对state字段聚合,被聚合的字段无需对分词统计,所以使用state.keyword对整个字段统计

查询所有

match_all表示查询所有的数据,sort即按照什么字段排序

  1. GET /bank/_search
  2. {
  3. "query": { "match_all": {} },
  4. "sort": [
  5. { "account_number": "asc" }
  6. ]
  7. }

分页查询(from+size)

本质上就是from和size两个字段

  1. GET /bank/_search
  2. {
  3. "query": { "match_all": {} },
  4. "sort": [
  5. { "account_number": "asc" }
  6. ],
  7. "from": 10,
  8. "size": 10
  9. }

指定字段查询:match

如果要在字段中搜索特定字词,可以使用match; 如下语句将查询address 字段中包含 mill 或者 lane的数据(分词索引)

  1. GET /bank/_search
  2. {
  3. "query": { "match": { "address": "mill lane" } }
  4. }

查询段落匹配:match_phrase

如果我们希望查询的条件是 address字段中包含 “mill lane”,则可以使用match_phrase(不分词索引)

  1. GET /bank/_search
  2. {
  3. "query": { "match_phrase": { "address": "mill lane" } }
  4. }

多条件查询: bool

如果要构造更复杂的查询,可以使用bool查询来组合多个查询条件。
例如,以下请求在bank索引中搜索40岁客户的帐户,但不包括居住在爱达荷州(ID)的任何人

  1. GET /bank/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. { "match": { "age": "40" } }
  7. ],
  8. "must_not": [
  9. { "match": { "state": "ID" } }
  10. ]
  11. }
  12. }
  13. }

must, should, must_not 和 filter 都是bool查询的子句。那么filter和上述query子句有啥区别呢?


查询条件:query or filter

先看下如下查询, 在bool查询的子句中同时具备query/must 和 filter

  1. GET /bank/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "match": {
  8. "state": "ND"
  9. }
  10. }
  11. ],
  12. "filter": [
  13. {
  14. "term": {
  15. "age": "40"
  16. }
  17. },
  18. {
  19. "range": {
  20. "balance": {
  21. "gte": 20000,
  22. "lte": 30000
  23. }
  24. }
  25. }
  26. ]
  27. }
  28. }
  29. }

两者都可以写查询条件,而且语法也类似。区别在于,query 上下文的条件是用来给文档打分的,匹配越好 _score 越高;filter 的条件只产生两种结果:符合与不符合,后者被过滤掉
所以,我们进一步看只包含filter的查询

  1. GET /bank/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "filter": [
  6. {
  7. "term": {
  8. "age": "40"
  9. }
  10. },
  11. {
  12. "range": {
  13. "balance": {
  14. "gte": 20000,
  15. "lte": 30000
  16. }
  17. }
  18. }
  19. ]
  20. }
  21. }
  22. }

聚合查询:Aggregation

我们知道SQL中有group by,在ES中它叫Aggregation,即聚合运算。

简单聚合—桶聚合

比如我们希望计算出account每个州的统计数量, 使用aggs关键字对state字段聚合,被聚合的字段无需对分词统计,所以使用state.keyword对整个字段统计

  1. GET /bank/_search
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "group_by_state": {
  6. "terms": {
  7. "field": "state.keyword"
  8. }
  9. }
  10. }
  11. }

因为无需返回条件的具体数据, 所以设置size=0,返回hits为空。
doc_count表示bucket中每个州的数据条数。

嵌套聚合—度量聚合

ES还可以处理个聚合条件的嵌套。
比如承接上个例子, 计算每个州的平均结余。涉及到的就是在对state分组的基础上,嵌套计算avg(balance):

  1. GET /bank/_search
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "group_by_state": {
  6. "terms": {
  7. "field": "state.keyword"
  8. },
  9. "aggs": {
  10. "average_balance": {
  11. "avg": {
  12. "field": "balance"
  13. }
  14. }
  15. }
  16. }
  17. }
  18. }

对聚合结果排序—管道聚合

可以通过在aggs中对嵌套聚合的结果进行排序
比如承接上个例子, 对嵌套计算出的avg(balance),这里是average_balance,进行排序

  1. GET /bank/_search
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "group_by_state": {
  6. "terms": {
  7. "field": "state.keyword",
  8. "order": {
  9. "average_balance": "desc"
  10. }
  11. },
  12. "aggs": {
  13. "average_balance": {
  14. "avg": {
  15. "field": "balance"
  16. }
  17. }
  18. }
  19. }
  20. }
  21. }

Term查询

DSL查询另一种极为常用的是对词项进行搜索,官方文档中叫”term level“查询,本文主要对term level搜索进行详解

字段是否存在:exist

id查询:ids

ids 即对id查找

  1. GET /test-dsl-term-level/_search
  2. {
  3. "query": {
  4. "ids": {
  5. "values": [3, 1]
  6. }
  7. }
  8. }

前缀:prefix

通过前缀查找某个字段

  1. GET /test-dsl-term-level/_search
  2. {
  3. "query": {
  4. "prefix": {
  5. "name": {
  6. "value": "Jan"
  7. }
  8. }
  9. }
  10. }

分词匹配:term

前文最常见的根据分词查询

  1. GET /test-dsl-term-level/_search
  2. {
  3. "query": {
  4. "term": {
  5. "programming_languages": "php"
  6. }
  7. }
  8. }

多个分词匹配:terms

按照读个分词term匹配,它们是or的关系

  1. GET /test-dsl-term-level/_search
  2. {
  3. "query": {
  4. "terms": {
  5. "programming_languages": ["php","c++"]
  6. }
  7. }
  8. }

按某个数字字段分词匹配:term set

设计这种方式查询的初衷是用文档中的数字字段动态匹配查询满足term的个数

  1. GET /test-dsl-term-level/_search
  2. {
  3. "query": {
  4. "terms_set": {
  5. "programming_languages": {
  6. "terms": [ "java", "php" ],
  7. "minimum_should_match_field": "required_matches"
  8. }
  9. }
  10. }
  11. }

通配符:wildcard

通配符匹配,比如*

  1. GET /test-dsl-term-level/_search
  2. {
  3. "query": {
  4. "wildcard": {
  5. "name": {
  6. "value": "D*ai",
  7. "boost": 1.0,
  8. "rewrite": "constant_score"
  9. }
  10. }
  11. }
  12. }

范围:range

常常被用在数字或者日期范围的查询

  1. GET /test-dsl-term-level/_search
  2. {
  3. "query": {
  4. "range": {
  5. "required_matches": {
  6. "gte": 3,
  7. "lte": 4
  8. }
  9. }
  10. }
  11. }

正则:regexp

通过正则表达式查询
以”Jan”开头的name字段

  1. GET /test-dsl-term-level/_search
  2. {
  3. "query": {
  4. "regexp": {
  5. "name": {
  6. "value": "Ja.*",
  7. "case_insensitive": true
  8. }
  9. }
  10. }
  11. }

模糊匹配:fuzzy

官方文档对模糊匹配:编辑距离是将一个术语转换为另一个术语所需的一个字符更改的次数。这些更改可以包括:

  • 更改字符(box→ fox)
  • 删除字符(black→ lack)
  • 插入字符(sic→ sick)
  • 转置两个相邻字符(act→ cat) ```json GET /test-dsl-term-level/_search { “query”: { “fuzzy”: {
    1. "remarks": {
    2. "value": "hell"
    3. }
    } } }

```