当搜索单个"已加星标的"时,Elasticsearch会为所有结果输出1.0分。术语

时间:2016-01-08 17:01:14

标签: elasticsearch

我们正在使用Elasticsearch搜索特定目录中最相关的公司。当我们使用像lettering这样的常规搜索字词时,我们会得到合理的分数,并可以根据分数对结果进行排序。

但是,当我们在查询之前修改搜索字词并制作"已加星标的"它的版本(例如,*lettering*)能够搜索子字符串,我们得到的每个结果得分为1.0。搜索子串是项目中的一项要求。

关于什么可能导致此相关性计算的任何想法?仅在使用单个术语时才会出现此问题。当我们组合使用两个加星标的术语时,我们会得到可理解的分数(例如,*lettering* *digital*)。

编辑1

示例性映射(YAML,其他属性以相同的方式映射,除了对每个属性不同的提升):

    elasticSearchMapping:
      type: object
      include_in_all: true
      enabled: true
      properties:
        'keywords':
          type: string
          include_in_all: true
          boost: 50

查询:

{
"query": {
    "filtered": {
        "query": {
            "bool": {
                "must": [{
                    "match_all": []
                }, {
                    "query_string": {
                        "query": "*lettering*"
                    }
                }]
            }
        },
        "filter": {
            "bool": {
                "must": [{
                    "term": {
                        "__parentPath": "/sites/industrycatalog"
                    }
                }, {
                    "terms": {
                        "__workspace": ["live"]
                    }
                }, {
                    "term": {
                        "__dimensionCombinationHash": "d751713988987e9331980363e24189ce"
                    }
                }, {
                    "term": {
                        "__typeAndSupertypes": "IndustryCatalog:Entry"
                    }
                }],
                "should": [],
                "must_not": [{
                    "term": {
                        "_hidden": true
                    }
                }, {
                    "range": {
                        "_hiddenBeforeDateTime": {
                            "gt": "now"
                        }
                    }
                }, {
                    "range": {
                        "_hiddenAfterDateTime": {
                            "lt": "now"
                        }
                    }
                }]
            }
        }
    }
},
"fields": ["__path"],
"script_fields": {
    "distance": {
        "script": "doc['coordinates'].distanceInKm(51.75631079999999,14.332867899999997)"
    }
},
"sort": [{
    "customer.featureFlags.industrycatalog": {
        "order": "asc"
    }
}, {
    "_geo_distance": {
        "coordinates": {
            "lat": "51.75631079999999",
            "lon": "14.332867899999997"
        },
        "order": "asc",
        "unit": "km",
        "distance_type": "plane"
    }
}],
"size": 999999

}

1 个答案:

答案 0 :(得分:7)

您正在做的是wildcard query,它们属于term level queries,默认情况下constant score已应用。

检查Lucene DocumentationWildcardQuery 延伸 MultiTermQuery

您也可以在explain api的帮助下验证这一点,您将会这样

"_explanation": {
     "value": 1,
     "description": "ConstantScore(company:lettering), product of:",
     "details": [{
         "value": 1,
         "description": "boost"
     }, {
         "value": 1,
         "description": "queryNorm"
     }]
 }

您可以使用rewriting

更改此行为

试试这个,rewrite也适用于query string query

{
  "query": {
    "wildcard": {
      "company": {
        "value": "digital*",
        "rewrite": "scoring_boolean"
      }
    }
  }
}

它有各种评分选项,看看哪些符合您的要求。

编辑1 ,您认为*lettering* *digital*的得分不是1的原因归因于queryNorm,您可以再次查看explain api,如果你看密切关注,两场比赛的所有文件都有相同的分数,单场比赛的文件也会有相同的分数。

P.S:根本不推荐领先的通配符。您将遇到性能问题,因为它必须检查inverted index中的每个单词。您可能需要检查edge ngramngram过滤器

希望这有帮助!