如何在 Elasticsearch 中提升给定搜索词的特定文档?

You*_*uxu 5 elasticsearch

我需要您在实际场景中的索引设计方面的帮助。这可能是一个很长的问题,让我尝试尽可能简洁地解释它。

我们正在构建一个基于 Elasticsearch 的搜索平台,为我们的客户提供站点搜索体验,索引中的文档可能是这样的:

{ "Path":"http://www.foo.com/doc/abc/1", "Title":"Title 1", "Description":"The description of doc 1", ... }
{ "Path":"http://www.foo.com/doc/abc/2", "Title":"Title 2", "Description":"The description of doc 2", ... }
{ "Path":"http://www.foo.com/doc/abc/3", "Title":"Title 3", "Description":"The description of doc 3", ... }
...
Run Code Online (Sandbox Code Playgroud)

对于每个查询,返回的命中文档默认按相关性排序,但我们的客户还希望针对某些关键字提升某些特定文档,

它们为我们提供了以下内容,例如提升配置 XML:

<boost>
    <Keywords value="keyword1">
        <Path rank="10000">http://www.foo.com/doc/abc/1</Path>
    </Keywords>

    <Keywords value="keyword2">
        <Path rank="10000">http://www.foo.com/doc/abc/2</Path>
        <Path rank="9900">http://www.foo.com/doc/abc/1</Path>
    </Keywords>

    <Keywords value="keyword3">
        <Path rank="10000">http://www.foo.com/doc/abc/3</Path>
        <Path rank="9900">http://www.foo.com/doc/abc/2</Path>
        <Path rank="9800">http://www.foo.com/doc/abc/1</Path>
    </Keywords>
</boost>
Run Code Online (Sandbox Code Playgroud)

这意味着,如果用户搜索“keyword1”,则前 1 个命中的文档应该是 Path 字段值为“ www.foo.com/doc/abc/1 ”的文档,而不管该文档的相关性得分如何。类似地,如果搜索“KEYWORD3”,前3命中文件应是其路径值为“文件www.foo.com/doc/abc/3 ”,“ www.foo.com/doc/abc/2 ”和“ www.foo。 com/doc/abc/1 " 分别。

为了满足这个特殊的需求,我的设计是,首先将原来的boosting XML转换成如下格式:

<boost>
    <Path value="http://www.foo.com/doc/abc/1">
        <keywords>
           <keyword value="keyword1" rank="10000" />
           <keyword value="keyword2" rank="9900" />
           <keyword value="keyword3" rank="9800" />
        </keywords>
    </Path>

    <Path value="http://www.foo.com/doc/abc/2">
        <keywords>
           <keyword value="keyword2" rank="10000" />
           <keyword value="keyword3" rank=9900" />
        </keywords>
    </Path> 
    <Path value="http://www.foo.com/doc/abc/3">
        <keywords>
           <keyword value="keyword3" rank="10000" />
        </keywords>
    </Path>
</boost>   
Run Code Online (Sandbox Code Playgroud)

然后向 Elasticsearch 文档添加一个嵌套字段“Boost”,其中包含一组关键字/排名字段,如下例所示:

{
  "Boost": [ 
     { "keyword":"keyword1", "rank": 10000},
     { "keyword":"keyword2", "rank": 9900},
     { "keyword":"keyword3", "rank": 9800}
  ] 
  "Path":"http://www.foo.com/doc/abc/1", 
  "Title":"Title 1", 
  "Description":"The description of doc 1",
   ...
 }

{
    "Boost": [ 
       { "keyword":"keyword2", "rank": 10000},
       { "keyword":"keyword3", "rank": 9900}
    ] 
    "Path":"http://www.foo.com/doc/abc/2", 
    "Title":"Title 2", 
    "Description":"The description of doc 2",
     ...
 }

{

    "Boost": [ 
       { "keyword":"keyword3", "rank": 10000}
    ] 
    "Path":"http://www.foo.com/doc/abc/3", 
    "Title":"Title 3", 
    "Description":"The description of doc 3",
     ...
}
Run Code Online (Sandbox Code Playgroud)

然后在查询时,使用嵌套查询获取给定搜索关键字的每个匹配文档的排名值,然后使用评分脚本根据此排名值调整相关性分数。

由于 boosting XML 的排名值远大于正常的相关性分数(一般小于 5),因此在 boosting XML 中为给定关键字配置的文档的调整分数应该是最高分。

你认为 Elasticsearch 上的设计是好的吗?对更好的方法有什么建议吗?

提前致谢!

ast*_*tax 3

最好将关键字与原始文档放在单独的字段中建立索引,然后在搜索过程中仅增强该字段中的匹配。

这与您所描述的不完全一样,因为它无法让您很好地控制每个关键字的提升因子。但是,如果查询包含特定关键字,这绝对是一种使特定文档在搜索结果中显示得更高的方法。

如果您确实需要更好地控制不同关键字的提升因子,您仍然可以使用此方法来实现。但是您需要创建几个“增强关键字”字段并在查询中以不同方式增强它们。

例如:

{ "Path":"http://www.foo.com/doc/abc/1",
  "Title":"Title 1",
  "Description":"The description of doc 1",
  "boost_kw1": "keyword1 keyword2",
  "boost_kw2": "keyword3 keyword4" },
{ "Path":"http://www.foo.com/doc/abc/1",
  "Title":"Title 1",
  "Description":"The description of doc 1",
  "boost_kw1": "keyword3",
  "boost_kw2": "keyword1 keyword2" }
Run Code Online (Sandbox Code Playgroud)

在查询中,您将总分计算为以下各项的总和:

  • 主要查询
  • “boost_kw1”中的比赛得分乘以 10
  • “boost_kw2”中的比赛得分乘以 5