我遇到了位置查询在ElasticSearch中返回错误结果的问题。
在我们的系统中,一个商业搜索引擎,每次搜索都需要两个输入:一个位置和一个查询字符串,例如
q=sushi
location=Greenwich Village, New York, New York
我希望搜索首先向我展示格林威治村的寿司,然后是格林威治村以外的寿司,但绝不向我展示非寿司的结果。
问题是,由于location
查询,格林威治村的所有内容都得到了匹配 - 律师,医生等等。我想对ElasticSearch说以下内容:
如果q匹配,那么位置不必(可以在格林威治村外返回寿司),但如果位置匹配,除非q匹配,否则不要返回它(不能返回非寿司业务)格林威治村)。
有人对如何做到这一点有任何想法吗?
答案 0 :(得分:2)
听起来你想搜索“寿司”(你不想要非寿司结果),但按位置排序你的结果(你想要格林威治村的结果首先)。
如果您将地点存储为地理位置,则只需使用距离sort即可获得结果。
如果location只是一个字段,并且您只能知道该商家是在某个位置的内部还是外部,则可以使用Custom Filters Score查询来提高所需位置的结果的相关性。 query
部分应包含对“sushi”的搜索,filters
部分应包含搜索位置。
答案 1 :(得分:0)
我在此帖子和here中包含了相关信息,以便提出以下解决方案。
使用中心点索引每个“地点”(邻域,城市等),并索引每个企业的坐标。
索引附加到包含它们的商家的地点ID。
使用子搜索将输入到位置栏的文本转换为地点记录。
使用CustomScoreQuery通过以下公式修改每个结果的分数,该公式是通过反复试验得出的:
new_score = old_score /(1 + distance_between_place_centerpoint_and_result)^ 3
还可以在place_ids字段中查询3的结果,作为'should'布尔查询。这样可以平稳地提升实际属于指定地点范围的所有内容。
这种策略的一个副作用是,靠近该地点中心点的商家被认为更具相关性 - 在我看来,这是否可以说是正确与否。但除此之外,它运作良好。
感谢imitov的洞察力帮助我提出了这个解决方案。