Elasticsearch常用查询实操之query_string

本文详细介绍Elasticsearch 6.8中query_string查询的使用技巧,包括统计总数、逻辑运算、分组聚合、过滤、去重、排序等实战示例,并展示了如何在日期处理和DSL编写上优化查询性能。

Elasticsearch常用查询实操之query_string

官方学习文档:
https://www.elastic.co/guide/en/elasticsearch/reference/6.8/index.html
1、es 7.X后,统计真实的所有数量,需要加上一个参数,"track_total_hits": true

{
  "track_total_hits": true,
  "query": {
    "match_all": {}
  }
}

2、AND、OR、NOT、exists、_missing_等关键字在query_string中的用法;

AND:表示条件与;
OR:表示条件或;
NOT:表示条件非;
_exists_:表示存在,且是存在对应字段;
_missing_:表示不存在或为空,此处为空建议用_exists_取非;
示例,如下DSL含义为:
查询 key_name_1 字段值为 value1,存在key_name_2字段,且key_time范围为time1到time2的所有数据,再按照时间字段key_time2及key_name_2字段进行分组;其中将时间字段key_time2格式化为yyyy-MM-dd HH的格式,"min_doc_count": 1,过滤分组结果大于等一1的数据
{
  "size": 0,
  "query": {
    "query_string": {
      "query": "key_name_1:value1 AND _exists_:key_name_2 AND key_time:[\"time1\" TO \"time2\"]"
    }
  },
  "aggs": {
    "group_by_time1": {
      "date_histogram": {
        "field": "key_time2",
        "interval": "day",
        "time_zone": "Asia/Shanghai",
        "format": "yyyy-MM-dd HH",
        "min_doc_count": 0
      },
      "aggs": {
        "group_by_key_name_2": {
          "terms": {
            "field": "key_name_2"
          }
        }
      }
    }
  }
}

3、having 用法,过滤分组结果

{
  "size": 0,
  "query": {
    "query_string": {
      "query": "key_name_1:value1"
    }
  },
  "aggs": {
    "group_key_name_2": {
      "terms": {
        "field": "key_name_2",
        "size": 1000
      },
      "aggs": {
        "having": {
          "bucket_selector": {
            "buckets_path": {
              "view_count": "_count"
            },
            "script": "params.view_count >1"
          }
        }
      }
    }
  }
}

4、cardinality 关键词,分组去重

{
  "aggs": {
    "group_by_key_name_1": {
      "cardinality": {
        "field": "key_name_1",
        "size": 100
      }
    }
  }
}

5、order的用法,可用于分组后再按内层结果排序

{
  "aggs": {
    "group_by_key_name_1": {
      "terms": {
        "field": "key_name_1",
        "size": 100,
        "order": {
          "dist_key_name_2": "desc"
        }
      },
      "aggs": {
        "dist_key_name_2": {
          "cardinality": {
            "field": "key_name_2"
          }
        }
      }
    }
  }
}

6、日期date存储为long类型时可以进行格式化

可用的时间间隔表达式有:
year-1y:表示1年;
quarter-1q:表示1季度;
month-1M:表示1个月;
week-1w:表示1星期;
day-1d:表示1天;
hour-1h:表示1小时;
minute-1m:表示1分钟;
second-1s:表示1秒;
用法示例:1.5h可以用分钟表示为90m;
时间格式:yyyy-MM-dd HH:mm:ss 其中大写的HH代表24小时制
用法示例:
{
  "aggs": {
    "group_by_time": {
      "date_histogram": {
        "field": "key_time",
        "interval": "hour",
        "time_zone": "Asia/Shanghai",
        "format": "yyyy-MM-dd HH",
        "min_doc_count": 0,
        "extended_bounds": {
          "min": "2020-12-06 00",
          "max": "2020-12-06 23"
        }
      }
    }
  }
}
Elasticsearch 中使用 `query_string` 进行通配符查询时,通常会结合字段的映射类型和分析器来决定查询行为。`wildcard` 查询是一种低效的查询方式,因为它通常需要遍历索引中的许多项,因此在际生产环境中应谨慎使用。如果希望在使用 `query_string` 时结合 `wildcard` 查询和 IK 分词器的行为,需要注意以下几点: 首先,`query_string` 查询默认会对输入的文本进行分词,而 IK 分词器(如 `ik_max_word` 或 `ik_smart`)会按照其配置对输入进行切分。然而,`wildcard` 查询不会使用标准的分词流程,而是直接匹配索引中的词条,因此即使使用了 IK 分词器,`wildcard` 查询仍然不会对输入进行分词处理。 如果希望在 `query_string` 查询中使用通配符语法,可以采用如下格式: ```json { "query": { "query_string": { "default_field": "content", "query": "框架*", "analyzer": "ik_max_word" } } } ``` 在此示例中,`query` 字段使用了通配符 `*` 来匹配以“框架”开头的词条,同时指定了 `analyzer` 为 `ik_max_word`,但这并不会影响通配符查询的行为,因为通配符查询不会触发分词[^4]。 为了优化查询性能并避免使用 `wildcard` 查询带来的潜在问题,可以考虑以下替代方案: 1. **ngram 分词器**:可以在索引映射中使用 `ngram` 分词器来预处理字段,这样可以支持部分匹配而无需使用 `wildcard` 查询。 2. **正则表达式查询**:在某些场景下,可以使用 `regexp` 查询代替 `wildcard` 查询,但同样需要注意其性能影响。 3. **前缀查询**:如果只需要匹配前缀,可以使用 `prefix` 查询,它比 `wildcard` 查询更高效。 此外,`match_phrase` 和 `multi_match` 查询更适合需要分词的场景,因为它们会利用分析器对输入进行处理[^3]。 ### 相关问题 1. 如何在 Elasticsearch 中优化通配符查询的性能? 2. 如何在 Elasticsearch 中配置 IK 分词器以支持中文搜索? 3. 什么是 ngram 分词器,它如何帮助优化部分匹配查询? 4. 在 Elasticsearch 中,`wildcard` 查询和 `regexp` 查询之间有什么区别? 5. 如何在 Elasticsearch现高效的前缀匹配查询
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值