MongoDB Atlas 搜索 - 搜索字符串中的多个术语具有 'and' 条件(不是 'or'

在 MongoDB Atlas 搜索的文档中,它对 autocomplete 说了以下内容运算符(operator):

query: String or strings to search for. If there are multiple terms in a string, Atlas Search also looks for a match for each term in the string separately.

对于text运算符,同样适用:

query: The string or strings to search for. If there are multiple terms in a string, Atlas Search also looks for a match for each term in the string separately.

分别匹配每个术语对我来说似乎很奇怪。我们需要在我们的应用程序中进行多次搜索,对于每次搜索,我们希望您键入的字词越多,搜索结果越少,而不是更多。

示例:搜索“John Doe”时,我希望只有同时包含“John”“Doe”的结果。目前,我得到的结果与“John”“Doe”相匹配。

使用 MongoDB Atlas Search 是不可能的,还是我做错了什么?


更新 目前,我已经通过在空格 (' ') 上拆分搜索词并将每个单独的关键字添加到单独的 must-sub-clause(使用复合运算符)来解决它。但是,如果只有一个关键字只有一个字符,则搜索查询将不再返回任何结果。考虑到这一点,我将具有一个字符的关键字与具有多个字符的关键字分开。 下面的代码片段有效,但为此我需要在每个文档上保存两个生成的字段:

  • searchString:所有可搜索字段串联而成的字符串。 F.e. “李四文街街市”
  • searchArray:将上述字符串大写并按空格(' ')分割成一个数组
const must = [];
const searchTerms = 'John D'.split(' ');
for (let i = 0; i < searchTerms.length; i += 1) {
    if (searchTerms[i].length === 1) {
      must.push({
        regex: {
          path: 'searchArray',
          query: `${searchTerms[i].toUpperCase()}.*`,
        },
      });
    } else if (searchTerms[i].length > 1) {
      must.push({
        autocomplete: {
          query: searchTerms[i],
          path: 'searchString',
          fuzzy: {
            maxEdits: 1,
            prefixLength: 4,
            maxExpansions: 20,
           },
         },
       });
    }
}
db.getCollection('someCollection').aggregate([
  {
    $search: {
      compound: { must },
    },
  },
]).toArray();

更新 2 - 意外行为的完整示例

使用以下文档创建集合:

db.getCollection('testing').insertMany([{
    "searchString": "John Doe ExtraTextHere"
    }, {
    "searchString": "Jane Doe OtherName"
    }, {
    "searchString": "Doem Sarah Thisistestdata"
    }])

在此集合上创建搜索索引“默认”:

{
  "mappings": {
    "dynamic": false,
    "fields": {
      "searchString": {
        "type": "autocomplete"
      }
    }
  }
}

执行以下查询:

db.getCollection('testing').aggregate([
  {
    $search: {
      autocomplete: {
        query: "John Doe",
        path: 'searchString',
        fuzzy: {
          maxEdits: 1,
          prefixLength: 4,
          maxExpansions: 20,
        },
      },
    },
  },
]).toArray();

当用户搜索“John Doe”时,此查询将返回路径“searchString”中包含“John”或“Doe”的所有文档。在此示例中,这意味着所有 3 个文档。用户键入的单词越多,返回的结果就越多。这不是预期的行为。我希望更多的词匹配更少的结果,因为搜索词变得更加精确。

最佳答案

edgeGram 标记化策略可能更适合您的用例,因为它是从左到右工作的。

试试这个取自 docs 的索引定义:

{
  "mappings": {
    "dynamic": false,
    "fields": {
      "searchString": [
        {
          "type": "autocomplete",
          "tokenization": "edgeGram",
          "minGrams": 3,
          "maxGrams": 10,
          "foldDiacritics": true
        }
      ]
    }
  }
}

此外,将您的查询子句从 must 更改为 filter。这将排除不包含所有标记的文档。

关于MongoDB Atlas 搜索 - 搜索字符串中的多个术语具有 'and' 条件(不是 'or' ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64428766/

相关文章:

python - Django 模型降序/嵌套查询

arrays - 如何将 numpy 数组转换为 Zarr 数组

python - 使用 python 控制包的错误奈奎斯特图

android - 如何从 Android 应用程序内部了解用户谷歌播放国家/地区?

javascript - 使用 React 根据另一个下拉列表更新选择的选项

angular - 如何在 Angular 10 应用程序仪表板中包含 firebase 分析?

python - 挣扎于基本的数据帧操作(Python)

azure - Terraform 对动态资源的 ignore_changes

html - 线性渐变不覆盖整个图像(留下 ~1px 边框)

json - Angular environment.ts 问题 JSON。然而 environme