MongoDB Atlas搜索 索引查询为必填项
我在Atlas Cloud DB里有这个搜索索引:
` { "mappings":
{ "dynamic": false,
"fields":
"email": [ { "maxGrams": 12, "minGrams": 3, "tokenization": "nGram", "type": "autocomplete" } ],
"firstName": [ { "maxGrams": 15, "minGrams": 2, "tokenization": "edgeGram", "type": "autocomplete" }, { "type": "string" } ],
"lastName": [ { "maxGrams": 15, "minGrams": 2, "tokenization": "edgeGram", "type": "autocomplete" }, { "type": "string" } ]
}
}`
现在我有不同的情况:我有 searchOn 个字段,作为 all, firstName, lastName, and email。当使用all进行搜索时,它应该在这三个字段中搜索字符串。当指定为 firstName、lastName 或 email 时,它应该在相应的字段中搜索字符串。现在,数据如下:
firstName, lastName, email
asad, gmail 1, [email protected]
asad, gmail 2, [email protected]
现在,情况如下:
通过选择 all:我应该在以下字符串中得到结果:asad、asad gmail、asad gmail 1、gmail 1、qa1、staftr等等。
通过选择 firstName:我应该在以下字符串中得到结果:asad、asa、sad。
通过选择 lastName:我应该在以下字符串中得到结果:gmail、gma、mail、gmail 1。
通过选择 email:我应该在以下字符串中得到结果:asad、asaduser、staftr、qa1、mail、gmail等等。
那么,Mongo的查询应该如何编写,才能在所有这些情形下都能工作?
解决方案
- 案例:
searchOn = "all"
{
$search: {
index: "your_index_name",
compound: {
should: [
{ autocomplete: { query: searchTerm, path: "firstName" } },
{ autocomplete: { query: searchTerm, path: "lastName" } },
{ autocomplete: { query: searchTerm, path: "email" } }
],
minimumShouldMatch: 1
}
}
}
- 案例:
searchOn = "firstName"/"lastName"/"email"
{
$search: {
index: "your_index_name",
autocomplete: {
query: searchTerm,
path: searchOn
}
}
}
我建议你按如下方式:
const buildSearchStage = (searchTerm, searchOn) => {
if (searchOn === "all") {
return {
$search: {
index: "your_index_name",
compound: {
should: [
{ autocomplete: { query: searchTerm, path: "firstName" } },
{ autocomplete: { query: searchTerm, path: "lastName" } },
{ autocomplete: { query: searchTerm, path: "email" } }
],
minimumShouldMatch: 1
}
}
};
}
return {
$search: {
index: "your_index_name",
autocomplete: {
query: searchTerm,
path: searchOn
}
}
};
};
这能干净地覆盖你所有的情况。
备选方案
你可以使用 text 来替代仅仅 autocomplete 。
{
$search: {
index: "your_index_name",
compound: {
should: [
{
text: {
query: searchTerm,
path: ["firstName", "lastName", "email"],
operator: "and"
}
},
{
autocomplete: {
query: searchTerm,
path: "firstName"
}
},
{
autocomplete: {
query: searchTerm,
path: "lastName"
}
},
{
autocomplete: {
query: searchTerm,
path: "email"
}
}
],
minimumShouldMatch: 1
}
}
}