我在S.O中看到了很多问题,并且阅读了有关"过滤器被缓存的文档"而查询不会被缓存,并且"查询将应用于所有值"如果在查询对象之外,则在查询之后应用"过滤器"等
最重要的是,文档很糟糕,DSL很难掌握。我尝试优化一些查询并使用kibana开发工具搜索分析器,但我的本地数据集必须太小才能衡量实际的性能差异(我在两个方向都得到了结果)而且我没有&# 39; t有一个带有多个节点的测试集群,可以对实际和大型数据集进行处理。
在这个简单的案例中,所有查询都会返回相同的结果。我想了解区别,为什么在任何情况下都希望将子句放在过滤器中而不是过滤器而不是过滤器
GET foo11/_search
{
"query": {
"bool": {
"filter": {
"match" : {
"in_stock" : true
}
}
}
}
}
GET foo11/_search
{
"query": {
"bool": {
"filter": {
"term" : {
"in_stock" : true
}
}
}
}
}
GET foo11/_search
{
"query": {
"bool": {
"must": {
"match" : {
"in_stock" : true
}
}
}
}
}
这3个案例的表现有何不同?我能否真正证明一个人比另一个更好/更差?
有什么区别:
"match" : {
"in_stock" : true
}
vs
"term" : {
"in_stock" : true
}
答案 0 :(得分:3)
有一些不同的问题和概念可供解包。
匹配与期限
match
个查询会执行分析(删除常见的停用词,阻止删除跟踪" ing"," es"等)您在索引中查找之前提供的搜索值。 分析的目标是使大致相同的词匹配,例如,如果您搜索"香蕉"但你索引"香蕉"它仍然会找到它。值得注意的是,对于此工作分析,索引数据时必须在字段上进行,这是Elasticsearch中text
类型字段的作用。
term
查询是完全匹配,未执行任何分析。这更像是您在关系数据库中习惯使用的内容。这些是针对keyword
字段和其他数据类型字段(数字,布尔值,日期)执行的。如果您需要匹配两种方式,则可以使用两种类型对字段建立索引。
查询与过滤
elasticsearch中的query
是一系列搜索子句,将根据其相关性对其进行评分和排名。换句话说,根据您要求我搜索的单词,哪些文档看起来最相关。
elasticsearch中的filter
限制查询运行的记录集,并且不会执行评分。您可以将其视为首次确定要检查哪些记录,然后再进行更昂贵的计算,以确定搜索词与每个文档的相关性。
您提及的另一个重要区别是filters
已缓存,但queries
未缓存。通常,如果您想要应用广泛的条件,您可以制作这些过滤器,并制作"人类文本"搜索部分查询。一般来说,如果您有广泛的限制,您可以限制可搜索的文档集,您可以将其放在过滤器中,以利用缓存和节省时间来避免评分。例如:仅过滤食谱中的产品,然后使用单词bananas查询标题。
效果衡量指标
测量查询性能可能很困难,因为混合中有很多移动部件。如果您有时间做的最佳方法是将代表(并且有些大)数据量索引到单个节点,然后在向外扩展之前对其进行初始测试。您可能还想查看Elasticsearch的性能测试工具,称为Rally。
https://github.com/elastic/rally
全部放在一起
对于上面的示例,由于您要搜索的字段是布尔值,因此您需要执行term
查询,而不是match
查询。此外,您可以在filter
子句中执行此操作,因为对于单个布尔值没有相关性评分。如果您想将其与其他文本搜索结合使用,可以在query
上下文中将一个匹配子句添加到您的json正文中。
答案 1 :(得分:0)
第二个更快
GET foo11/_search
{
"query": {
"bool": {
"filter": {
"term" : {
"in_stock" : true
}
}
}
}
}
它更快的原因: - 过滤器不会对您的文档进行评分。 - 术语将与确切的单词匹配,跳过分析部分。
更多参考: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html