如何通过 Elasticsearch 实现复杂的查询过滤条件?
如何通过 Elasticsearch 实现复杂的查询过滤条件?
回答重点
通过 Elasticsearch 实现复杂的查询过滤条件,通常需要使用其强大的搜索查询 DSL(Domain Specific Language)。具体来说,可以借助 Bool Query 来结合多个查询条件(must、should、must_not、filter)实现复杂的逻辑筛选。下面是一个实际例子,通过 Bool Query 实现复杂的查询:
1 | { |
这里的查询条件实现了这样一种逻辑:必须满足 status 为 active 和 age 大于等于 30,同时性别是 male,优先推荐 subscription 为 premium,不包括 country 为 USA 的记录。
扩展知识
1)查询子句解读:
- must:必须匹配的查询条件,相当于逻辑“AND”。在上面的例子中,仅查找 status 为 active 而且 age 大于等于 30 的文档。
- filter:用于过滤文档,但它不影响评分计算。这个在性能上会更高效,适用于那些不需要评分计算的条件。在这里,我们过滤性别为 male 的文档。
- should:可选的查询条件,相当于逻辑“OR”。匹配 should 子句中的任意一个条件将提升文档的相关性评分。在这个例子中,是为了找到 subscription 为 premium 的文档。
- must_not:必须排除的查询条件,即不符合这些条件的文档。这个例子中,我们排除 country 为 USA 的文档。
2)评分和优化:
在实际应用中,经常会遇到需要评分(scoring)和排序的情况。Elasticsearch 的 scoring 会根据查询条件的权重(boost)以及文档的相关性评分返回查询结果。对于时间敏感和性能敏感的查询,可以使用 filter 子句,因为它不会计算相关性评分,从而提升查询性能。
3)嵌套查询和子查询:
对于更为复杂的条件,可以使用 nested query 来处理嵌套对象,使用子查询可以更灵活地组合多个查询逻辑。例如,使用 nested 子句处理带有嵌套结构的 JSON 数据:
1 | { |
这个例子用于查询 comments 里 user 为 kimchy 且 date 大于等于 2022-01-01 的记录。
4)使用脚本进行高级查询:
Elasticsearch 允许使用脚本进行更高级的查询,尽管这可能会耗费更多资源。在 _score 子句里可以用脚本来控制评分逻辑。例如,用一个简单的 Painless 脚本来进行自定义评分:
1 | { |
这个例子中,评分由文档的 views 值乘以匹配查询的默认评分值。