ES查询
1、精准查询
要实现精确查询,你可以使用 Elasticsearch 的 term 查询。term 查询将按照精确值进行搜索,因此可以用来实现精确查询。
以下是一个示例:
假设你有一个名为 "users" 的索引,其中包含一个名为 "name" 的字段,你想要搜索名为 "John" 的用户。你可以使用以下查询:
GET /users/_search { "query": { "term": { "name": "John" } } }
此查询将返回所有名为 "John" 的用户。请注意,term 查询是大小写敏感的,因此它会将 "John" 与 "john" 视为不同的值。
如果你希望实现大小写不敏感的精确查询,你可以使用 keyword 字段。例如:
GET /products/_search { "query": { "fuzzy": { "title": { "value": "apple", "fuzziness": 2 } } } }
GET /users/_search { "query": { "term": { "name.keyword": "john" } } }
2、模糊查询
在 Elasticsearch 中,可以使用多种方法实现模糊查询。以下是一些常用的模糊查询实现方式:
- 通配符查询(Wildcard Query):通配符查询可以使用通配符符号(和?)进行匹配。代表零个或多个字符,?代表单个字符。例如,“appl*”可以匹配“apple”和“application”等单词。通配符查询虽然简单,但在处理大数据时性能相对较差。
- 正则表达式查询(Regexp Query):正则表达式查询允许你使用正则表达式来匹配文档中的字符串。例如,使用正则表达式“^a.*e$”可以匹配以“a”开头,以“e”结尾的字符串。
- 模糊查询(Fuzzy Query):模糊查询允许你在一定范围内进行模糊匹配。它使用编辑距离算法来计算字符串之间的相似度。你可以通过设置“prefix_length”参数来指定模糊匹配的起始位置。
- 跨度查询(Span Query):跨度查询用于在两个连续的文本之间进行匹配。它可以在两个关键词之间进行匹配,或者在一段文本中查找重复的子串。
这些是 Elasticsearch 中常用的模糊查询方法,你可以根据具体需求选择适合的方法进行模糊匹配。
举例:
2.1 Wildcard Query通配符查询
假设你有一个名为 "users" 的索引,其中包含一个名为 "username" 的字段,你想要搜索以 "ap" 开头的用户名。你可以使用通配符查询来实现这个匹配:
在这个例子中,通配符查询使用 "" 表示任意字符序列,因此 "ap" 可以匹配以 "ap" 开头的任意用户名,例如 "app"、"apple"、"appl" 等。
需要注意的是,通配符查询在大数据集上可能效率较低,因为它们需要遍历索引中的每个文档进行匹配。因此,在处理大量数据时,建议使用其他查询方式,如正则表达式查询或模糊查询,以提高查询性能。
GET /users/_search { "query": { "wildcard": { "username": "ap*" } } }
2.2 Regexp Query
假设你有一个名为 "products" 的索引,其中包含一个名为 "description" 的字段,你想要搜索所有描述中包含字母 "a" 或 "e" 的产品。你可以使用正则表达式查询来实现这个匹配:
GET /products/_search { "query": { "regexp": { "description": "[ae]" } } }
2.3 模糊查询(Fuzzy Query)
GET /products/_search { "query": { "fuzzy": { "title": { "value": "apple", "fuzziness": 2 } } } }
在这个例子中,Fuzzy 查询对 "title" 字段进行模糊匹配,查找与 "apple" 相似的产品。通过设置 "fuzziness" 参数为 2,你可以控制模糊匹配的相似度。
需要注意的是,Fuzzy 查询的性能可能会受到大数据集的影响。如果你需要处理大量数据并需要提高查询性能,可以考虑使用其他查询方式,如通配符查询或正则表达式查询。
在 Elasticsearch 中,Fuzzy 查询的 fuzziness
参数用于控制模糊匹配的相似度。fuzziness
参数的值是一个非负整数,表示允许的最大编辑距离。
编辑距离是指将一个字符串转换为另一个字符串所需要的最小字符更改次数。编辑距离为 0 表示两个字符串完全相同,编辑距离为 1 表示两个字符串只有一个字符不同,以此类推。
通过设置 fuzziness
参数的值,你可以控制模糊匹配的范围。较小的 fuzziness
值将限制模糊匹配的范围,只返回与查询字符串非常相似的结果。较大的 fuzziness
值将扩大模糊匹配的范围,返回更多与查询字符串相似的结果。
在上面的示例中,fuzziness
参数设置为 2,表示允许最大的编辑距离为 2,即允许两个字符之间的差异。这意味着查询将返回与 "apple" 相似的产品,即使它们的标题与 "apple" 有两个字符的差异。
2.4 跨度查询(Span Query)
假设你有一个名为 "posts" 的索引,其中包含一个名为 "content" 的字段,你想要找到包含关键词 "apple" 和 "orange" 之间的文本。你可以使用跨度查询来实现这个匹配:
GET /posts/_search { "query": { "span_term": { "content": "apple orange" } } }
3.0 日期范围查询
在这个例子中,我们查询 "logs" 索引,筛选出 "timestamp" 字段的值在 2023 年 1 月 1 日到 2023 年 12 月 31 日之间的文档。gte
表示 "大于或等于",lte
表示 "小于或等于"。
你可以根据需要调整日期范围,并使用其他日期格式。确保在查询中使用的日期格式与索引中存储的日期格式相匹配。
GET /logs/_search { "query": { "range": { "timestamp": { "gte": "2023-01-01", "lte": "2023-12-31" } } } }
4.0 排序:
在Elasticsearch中,可以使用sort
参数来指定排序规则。sort
参数接受一个数组,数组中的每个元素表示一个排序规则。排序规则由字段名和排序顺序组成,其中字段名可以是文档中的任意字段,排序顺序可以是升序(asc)或降序(desc)。
以下是一个示例查询,按照"create_time"字段升序排序:
GET /megacorp/employee/_search { "sort": [ { "create_time": { "order": "asc" } } ], "query": { "match_all": {} } }
5.0 es 分页
在Elasticsearch中,分页是通过使用from
和size
参数来实现的。这两个参数可以让你指定从哪个位置开始获取结果以及要获取的结果数量。
from
参数用于指定起始位置,从0开始计数。size
参数用于指定要返回的结果数量。
例如,如果你想从第10个位置开始获取20条结果,可以这样写查询:
这个查询会返回索引your_index
中满足match_all
查询的前20个文档,从第10个位置开始。请注意,由于结果是从0开始计数的,所以from
参数的值应该比你想开始的位置大1。
需要注意的是,Elasticsearch的分页是基于游标的,这意味着每次查询都会返回一个新的游标。如果你需要连续分页,需要保存上一次查询的游标,并在下一次查询中使用这个游标作为新的起始点。
GET /your_index/_search { "from": 9, "size": 20, "query": { "match_all": {} } }
6.0 聚合函数
avg:
GET /sales/_search { "size": 0, "aggs": { "avg_price": { "avg": { "field": "price" } } } }
sum:
GET /sales/_search { "size": 0, "aggs": { "total_sales": { "sum": { "field": "price" } } } }
max
GET /sales/_search { "size": 0, "aggs": { "min_price": { "min": { "field": "price" } }, "max_price": { "max": { "field": "price" } } } }
goup by
GET /sales/_search { "size": 0, "aggs": { "group_by_category": { "terms": { "field": "category.keyword" }, "aggs": { "group_size": { "sum": { "field": "price" } } } } } }
在上述示例中,我们使用了terms
聚合来按category.keyword
字段对文档进行分组。然后,在每个分组内部,我们使用sum
聚合来计算price
字段的总和。
通过这种方式,你可以根据需要使用不同的聚合函数来对分组进行计算和分析。请注意,在聚合查询中,将size
参数设置为0,因为我们只对聚合结果感兴趣,而不是实际的文档内容。