一、查询和过滤器的区别
在 Elasticsearch 中,查询(Query)和过滤器(Filter)是用于检索和筛选数据的重要组成部分。它们虽然都能用来查找文档,但在性能和用法上有所不同。下面详细介绍查询和过滤器的概念以及它们之间的区别。
查询 (Query)
查询不仅用于查找匹配的文档,还可以计算相关性得分(_score
),以确定文档与查询的匹配程度。查询通常用于全文搜索、短语匹配等场景,其中文档的相关性非常重要。
过滤器 (Filter)
过滤器用于精确筛选文档,不计算相关性得分。因此,过滤器比查询更快,因为它们不需要计算分数。过滤器通常用于过滤特定条件的文档,如日期范围、特定值等。
性能差异
- 查询:计算相关性得分,性能相对较低。
- 过滤器:不计算相关性得分,性能较高,适合用于频繁使用的条件。
使用场景
- 查询:当需要根据相关性排序结果时,例如全文搜索、推荐系统等。
- 过滤器:当需要精确筛选文档时,例如日期范围、类别过滤等。
组合使用
在实际应用中,查询和过滤器经常一起使用,以达到最佳效果。例如,可以使用 bool
查询来组合查询和过滤器:
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "Elasticsearch"
}
}
],
"filter": [
{
"range": {
"publish_date": {
"gte": "2023-01-01",
"lte": "2023-12-31"
}
}
}
]
}
}
}
在这个例子中:
must
子句中的match
查询用于全文搜索标题中包含 “Elasticsearch” 的文档。filter
子句中的range
过滤器用于筛选publish_date
在 2023 年内的文档。
二、ElasticSearch的查询类型
Elasticsearch 提供了多种查询类型,每种类型都有其特定的用途和适用场景。下面是一些常见的查询类型及其简要说明:
1. 全文查询 (Full Text Queries)
这些查询类型用于全文搜索,可以处理复杂的自然语言查询。
-
Match Query: 最常用的全文查询,可以处理分析器对文本的分析。
{ "match": { "field": "text" } }
-
Multi Match Query: 类似于
match
查询,但可以在多个字段上进行搜索。{ "multi_match": { "query": "text", "fields": ["field1", "field2"] } }
-
Match Phrase Query: 用于匹配完整的短语,而不是单独的词项。
{ "match_phrase": { "field": "text" } }
-
Match Phrase Prefix Query: 类似于
match_phrase
,但允许前缀匹配。{ "match_phrase_prefix": { "field": "text" } }
-
Common Terms Query: 用于查找常见词和不常见词,可以控制如何处理低频词和高频词。
{ "common": { "field": { "query": "text", "cutoff_frequency": 0.001 } } }
2. 术语级别查询 (Term Level Queries)
这些查询类型用于精确匹配,不涉及分析器。
-
Term Query: 用于精确匹配单个词项。
{ "term": { "field": "value" } }
-
Terms Query: 用于匹配多个词项。
{ "terms": { "field": ["value1", "value2"] } }
-
Range Query: 用于匹配某个范围内的值。
{ "range": { "field": { "gte": 10, "lte": 20 } } }
-
Exists Query: 用于检查某个字段是否存在。
{ "exists": { "field": "field" } }
-
Prefix Query: 用于前缀匹配。
{ "prefix": { "field": "pre" } }
-
Wildcard Query: 用于通配符匹配。
{ "wildcard": { "field": "te*t" } }
-
Regexp Query: 用于正则表达式匹配。
{ "regexp": { "field": "te.*t" } }
3. 布尔查询 (Compound Queries)
这些查询类型用于组合多个查询条件。
-
Bool Query: 用于组合多个查询条件,支持
must
,should
,must_not
,filter
子句。{ "bool": { "must": [ { "match": { "field1": "text" } } ], "should": [ { "match": { "field2": "text" } } ], "must_not": [ { "match": { "field3": "text" } } ], "filter": [ { "range": { "field4": { "gte": 10 } } } ] } }
-
Dis Max Query: 用于在多个字段上进行查询,并选择最相关的文档。
{ "dis_max": { "queries": [ { "match": { "field1": "text" } }, { "match": { "field2": "text" } } ] } }
-
Constant Score Query: 用于将查询转换为固定得分。
{ "constant_score": { "filter": { "term": { "field": "value" } } } }
4. 特殊查询 (Specialized Queries)
这些查询类型用于特定的高级功能。
-
Function Score Query: 用于自定义文档的得分。
{ "function_score": { "query": { "match_all": {} }, "functions": [ { "gauss": { "field": { "origin": "2023-01-01", "scale": "10d" } } } ] } }
-
Script Score Query: 用于使用脚本计算文档的得分。
{ "script_score": { "query": { "match_all": {} }, "script": { "source": "doc['field'].value * 2" } } }
-
More Like This Query: 用于查找与给定文档相似的文档。
{ "more_like_this": { "fields": ["field1", "field2"], "like": "text", "min_term_freq": 1, "min_doc_freq": 1 } }
5. 地理查询 (Geo Queries)
这些查询类型用于地理空间数据的搜索。
-
Geo Distance Query: 用于查找距离指定点一定范围内的文档。
{ "geo_distance": { "distance": "200km", "location": { "lat": 40.715, "lon": -74.006 } } }
-
Geo Bounding Box Query: 用于查找位于指定矩形区域内的文档。
{ "geo_bounding_box": { "location": { "top_left": { "lat": 40.73, "lon": -74.00 }, "bottom_right": { "lat": 40.71, "lon": -73.99 } } } }
-
Geo Polygon Query: 用于查找位于指定多边形区域内的文档。
{ "geo_polygon": { "location": { "points": [ { "lat": 40.73, "lon": -74.00 }, { "lat": 40.73, "lon": -73.99 }, { "lat": 40.71, "lon": -73.99 }, { "lat": 40.71, "lon": -74.00 } ] } } }
6. 其他查询
-
Match All Query: 返回所有文档,常用于获取索引中的所有数据。
{ "match_all": {} }
-
Match None Query: 不返回任何文档,常用于测试或调试。
{ "match_none": {} }
三、ElasticSearch的过滤器类型
在 Elasticsearch 中,过滤器(Filter)用于精确筛选文档,不计算相关性得分,因此性能较高。下面是一些常见的过滤器类型及其简要说明:
1. 术语级别过滤器 (Term Level Filters)
这些过滤器用于精确匹配,不涉及分析器。
-
Term Filter: 用于精确匹配单个词项。
{ "term": { "field": "value" } }
-
Terms Filter: 用于匹配多个词项。
{ "terms": { "field": ["value1", "value2"] } }
-
Range Filter: 用于匹配某个范围内的值。
{ "range": { "field": { "gte": 10, "lte": 20 } } }
-
Exists Filter: 用于检查某个字段是否存在。
{ "exists": { "field": "field" } }
-
Prefix Filter: 用于前缀匹配。
{ "prefix": { "field": "pre" } }
-
Wildcard Filter: 用于通配符匹配。
{ "wildcard": { "field": "te*t" } }
-
Regexp Filter: 用于正则表达式匹配。
{ "regexp": { "field": "te.*t" } }
2. 布尔过滤器 (Boolean Filters)
这些过滤器用于组合多个过滤条件。
- Bool Filter: 用于组合多个过滤条件,支持
must
,should
,must_not
,filter
子句。{ "bool": { "must": [ { "term": { "field1": "value1" } } ], "should": [ { "term": { "field2": "value2" } } ], "must_not": [ { "term": { "field3": "value3" } } ], "filter": [ { "range": { "field4": { "gte": 10 } } } ] } }
3. 特殊过滤器 (Specialized Filters)
这些过滤器用于特定的高级功能。
-
Script Filter: 用于使用脚本进行复杂的条件判断。
{ "script": { "script": { "source": "doc['field'].value > 10" } } }
-
Ids Filter: 用于匹配特定的文档 ID。
{ "ids": { "values": ["1", "2", "3"] } }
4. 地理过滤器 (Geo Filters)
这些过滤器用于地理空间数据的筛选。
-
Geo Distance Filter: 用于查找距离指定点一定范围内的文档。
{ "geo_distance": { "distance": "200km", "location": { "lat": 40.715, "lon": -74.006 } } }
-
Geo Bounding Box Filter: 用于查找位于指定矩形区域内的文档。
{ "geo_bounding_box": { "location": { "top_left": { "lat": 40.73, "lon": -74.00 }, "bottom_right": { "lat": 40.71, "lon": -73.99 } } } }
-
Geo Polygon Filter: 用于查找位于指定多边形区域内的文档。
{ "geo_polygon": { "location": { "points": [ { "lat": 40.73, "lon": -74.00 }, { "lat": 40.73, "lon": -73.99 }, { "lat": 40.71, "lon": -73.99 }, { "lat": 40.71, "lon": -74.00 } ] } } }
5. 其他过滤器
-
Match All Filter: 返回所有文档,常用于获取索引中的所有数据。
{ "match_all": {} }
-
Match None Filter: 不返回任何文档,常用于测试或调试。
{ "match_none": {} }