在 MongoDB Atlas 搜索中具有相同搜索分数的多个文档

Multiple documents having equal search score in MongoDB Atlas Search

有没有办法提高 Atlas 搜索中精确匹配的分数?

我在将 'hi' 的 right/best 从英文翻译成法文时遇到问题。经过一些调试后,我发现从我的聚合中返回的前三 (3) 个文档每个都具有相同的分数“2.362138271331787”。

我希望 'hi' 有更高的分数,因为它与相同的搜索查询完全匹配,但 'it’s his' 和 'his' 似乎与'hi'.

这是我的搜索查询:

const searchOption= [
  {
    $search: {
      text: {
        query: 'hi',
        path: 'english',
      },
    },
  },
  { $project: {  _id: 0, french: 1, english: 1, score: { $meta: "searchScore" } } },
  { $limit: 5 },
];

const result = await Greetings.aggregate(searchOption, { cursor: { batchSize: 5 } }).toArray();

这是返回的文件。该列表按搜索分数排序:

[
  {
    "english": "it’s his",
    "french": "c'est le sien",
    "score": 2.362138271331787
  },
  {
    "english": "hi",
    "french": "salut",
    "score": 2.362138271331787
  },
  {
    "english": "his",
    "french": "le sien",
    "score": 2.362138271331787
  },
  {
    "english": "it’s his failure to arrange his",
    "french": "c'est son incapacité à organiser son",
    "score": 2.2482824325561523
  },
  {
    "english": "it’s his failure to arrange his time",
    "french": "c'est son incapacité à organiser son temps",
    "score": 2.0995540618896484
  }
]

分数是由 Mongo 内部实现的“相关性分数”,我会说令我惊讶的是字段长度不是分数的一部分,即使它是“文本”操作数,我会个人预计近期会以某种形式加入

现在您可以使用一种变通方法来构造您想要的分数,例如,您可以使用 should(或)表达式和 phrase 运算符结合提升分数函数,例如所以:

const searchOption= [
    {
        $search: {
            "compound": {
                "should" : [
                    {
                        "phrase":{
                            "query": "hi",
                            "path": "english",
                            "score": {"boost":{"value":5}} 
                        }
                    },
                    {
                        text: {
                            query: 'hi',
                            path: 'english',
                        },
                    },
                ]
            }
        }
    },
    { $project: {  _id: 0, french: 1, english: 1, score: { $meta: "searchScore" } } },
    { $limit: 5 },
];

const result = await Greetings.aggregate(searchOption, { cursor: { batchSize: 5 } }).toArray();

否则你也可以只按 english 长度结合分数排序(这是假设分数会并列),显然这不是真正的排序,因为它假设前 5 个结果是您期望获得的实际前 5 个结果。

const searchOption= [
    {
        $search: {
            text: {
                query: 'hi',
                path: 'english',
            },
        },
    },
    { $project: {  _id: 0, french: 1, english: 1, score: { $meta: "searchScore" }, len: {$strLenCP: "$english"} } },
    { $sort : { score: -1, len: -1 } },
    { $limit: 5 },
];

const result = await Greetings.aggregate(searchOption, { cursor: { batchSize: 5 } }).toArray();

这是 Atlas Search 的一个已知限制,解决方案在此处提到: https://www.mongodb.com/docs/atlas/atlas-search/autocomplete/#limitations

lucene.keyword 分析器非常有助于在分数保真度至关重要的情况下进行精确匹配。

基本上,路径英语应该在索引定义中定义为自动完成和字符串,如:

[
  {"type": "string"},
  {"type": "autocomplete"}
]

以上假设您没有使用自动完成或字符串的语言分析器,这可能并不理想,因为根据用例,它们都应该是英语分析器。

然后,在查询端,您需要一个 compound 查询,其中两个选项都是 should 子句。您应该提升 text 子句而不是自动完成子句。