我正在查看一些旧代码,以及是否有必要对其进行重构以提高性能。
想法是...使用function_score,您正在将一个函数应用于要返回的所有文档,因此,如果只能在所需的文档上运行这些函数,那会更好。
当前的完成方式有点像这样(我简化了查询,在这里讨论):
{
"query": {
"bool": {
"must": {
"function_score": {
"query": {
"match_all": {}
},
"functions": [
{
"gauss": {
"updated_at": {
"origin": "now",
"scale": "7d",
"offset": "2d",
"decay": 0.5
}
}
}
]
}
},
"filter": [
{
"bool": {
"must": [
{
"term": {
"indexed": true
}
}
],
"must_not": [
{
"terms": {
"sale_stage": [
"on_hold",
"withdrawn",
"off_market"
]
}
}
],
}
}
]
}
},
"sort": [
"_score",
"_uid"
],
}
查询的内容并不重要。重要的是,在功能得分之外还有过滤器。
查询运行正常,并返回正确的数据。但是,我是否认为分数函数正在索引中的所有文档上运行,然后进行过滤,还是ES足够聪明,可以在此处进行优化,因为它知道我想要过滤后的数据集?
换句话说,我是否可以保留查询,还是应该将其变成这样:
{
"query": {
"bool": {
"must": {
"function_score": {
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": [
{
"bool": {
"must": [
{
"term": {
"indexed": true
}
}
],
"must_not": [
{
"terms": {
"sale_stage": [
"on_hold",
"withdrawn",
"off_market"
]
}
}
]
}
}
]
}
},
"functions": [
{
"gauss": {
"updated_at": {
"origin": "now",
"scale": "7d",
"offset": "2d",
"decay": 0.5
}
}
}
]
}
}
}
},
"sort": [
"_score",
"_uid"
],
}
在第二个示例中,查询的目的是相同的,但是我将所有过滤移到了评分功能中。原因是,如果我有一个非常昂贵的功能(例如地理间距的东西),我不想在每个文档上都运行它。
我是否需要进行这种小的重构,还是因为ES为此而进行了优化,所以不必要吗?
答案 0 :(得分:1)
您可以将过滤器保留在function_score
查询之外。这样的想法是,如果您有多个function_score
查询,则过滤仅执行一次,然后所有功能分数都将在过滤后的数据集上运行。
此外,如果您除了function_score
查询之外还具有汇总,则一定要让过滤器位于外部,以便也可以在精简文档集中计算汇总。过滤器都是为了减少需要运行昂贵计算的文档集。