Mongodb的$concat需要一个新的索引



我有一个拥有数百万数据的数据库。这些数据包含名称但我有两种类型的名称

具有给定名称的数据(denomination键)

具有人名的数据(firstNamelastName键,我没有在数据中连接两者的键)

我想创建一个API,搜索给定名称和人名的查询

为此,我必须在denomination键和连接的firstNamelastName键上搜索查询

这就是为什么我首先将firstNamelastName键连接到identity键。

然后我想做一个聚合来匹配我对这两个键的查询

aggregate([
{$addFields:{'identite':{$concat:["$lastName",' ',"$firstName"]}}},
{
$match:{
$and:[{
$or : [
{
'denomination':toUpper(MySearchQuery])
},
{
'identite':toUpper(MySearchQuery)
}
]
}
/*Here, i'll be able to add more conditions*/
]
}
}
])

我的问题是在这种情况下如何管理索引?我是否必须索引我的连接键(identity,但它不存在于我的数据)和denomination。或者我必须索引firstName,lastNamedenomination

如果你有更好的解决方案来做我的搜索,我也接受

提前感谢。

在您的示例中,只有第一个$match阶段将使用.aggregation查询中的索引进行改进。在这种情况下,您需要修改查询:

.aggregate([
{
$match: {
firstName: "John",
lastName: "Doe",
}
},
...
])
并为您的集合创建一个复合索引,如:{ firstName: 1, lastName: 1 }

你可能想检查这篇文章,特别是管道操作符和索引部分从MongoDB文档。

更新根据你的问题:

问题是我将无法分离firstName和lastName。它就像一个搜索栏,你可以在同一个查询中输入firstName和lastName。这就是为什么我要把它们连接起来

有多种方法可以实现它。最好的方法是使用$text索引和文本搜索。我每天在一个有100多万个文档的生产数据库上使用它。

Mongoose文本索引示例:

YourSchema.index(
{
'firstName': 'text',
'lastName': 'text',
},
{
weights:
{
'firstName': 2,
'lastName': 1
},
name: 'SearchQuery',
})

这是一个用于在多个字段中搜索的文本索引的示例。但是,如果您想寻找Joe Doe作为firstName & lastName的组合,您也可以使用虚拟字段(不确定100%)或为文本索引添加单独的字段,如:

收集模式

{
firstName: string,
lastName: string,
// ++combinedName: string
}

,然后为combinedName字段添加单独的文本索引。

v2更新

不幸的是,您不能在您的情况下使用猫鼬虚拟,最好的方法是创建另一个与firstLastName相结合的字段,并添加一个具有适当权重的$text查询索引(实际上支持语言和大小写敏感搜索)到denominationfirstLastName字段,如我上面所述。

另一个相关的,但不是MongoDB的选项是在ElasticSearch中存储部分集合。

是避免用户搜索查询(反应时间很敏感,不应该超过2s)的性能问题的唯一方法,并且不需要重新构建整个模式。

你也可以让它成为可能,如果你使用mongoose驱动的mongo,与default属性,在那里你可以从this.lastNamethis.lastName预定义你的firstLastName值,所以你不需要每次手动添加它。

但是,当然,第一次,您需要通过游标更新整个连接:

await YourModel
.find()
.cursor()
//.sort(by proprery not sure)
.eachAsync(async (doc) => {
doc.firstLastName = `${doc.firstName} ${doc.lastName}`;
await doc.save();
})

updateMany(但updateMany是长查询,不像游标那么好控制)

相关内容

  • 没有找到相关文章

最新更新