MongoDB Atlas Search - 搜索字符串中的多个术语,带有'and'条件(不是"or")



在MongoDB Atlas搜索的文档中,它对autocomplete运算符表示如下:

query:要搜索的字符串。如果中有多个术语一个字符串,Atlas Search还会为单独的字符串。

对于text运算符,同样的情况也适用:

query:要搜索的字符串。如果有多个字符串中的术语,Atlas Search还会为每个术语查找匹配项分别在字符串中。

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

示例:当搜索";John Doe";,我只期望两者都有结果;约翰";Doe";。目前,我得到的结果与";约翰";Doe";。

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


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

  • searchString:连接所有可搜索字段的字符串。F.e.";John Doe Man Streetstreet Citycity
  • 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";,该查询返回所有具有";约翰;OR";Doe";在路径";searchString";。在本例中,这意味着所有3个文档。用户键入的单词越多,返回的结果就越多。这不是预期的行为。我希望更多的单词匹配更少的结果,因为搜索词变得更精确。

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

尝试从文档中获取此索引定义:

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

另外,添加将查询子句从"必须"更改为"筛选"。这将排除不包含所有令牌的文档。

相关内容

最新更新