我有一個包含數百萬資料的資料庫。這些資料包含名稱,但我有兩種型別的名稱
具有給定名稱(denomination鍵)的資料
或者
帶有人名的資料(firstName和lastName鍵,我沒有將資料中的兩者連接起來的鍵)
我想創建一個 API 來搜索給定名稱和人名的查詢
為此,我必須在denomination鍵和連接firstName lastName鍵上搜索查詢
這就是為什么我,首先,CONCATfirstName和lastName鑰匙進入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,lastName并且denomination
如果你有更好的解決方案讓我搜索,我也接受
提前致謝。
uj5u.com熱心網友回復:
在您的情況下,查詢中$match的索引只會改進第一階段.aggregation。在這種情況下,您需要修改查詢:
.aggregate([
{
$match: {
firstName: "John",
lastName: "Doe",
}
},
...
])
并為您的集合創建一個復合索引,例如: { firstName: 1, lastName: 1 }
您可能想查看這篇文章,尤其是MongoDB 檔案中的Pipeline Operators 和 Indexes 部分。
更新
根據你的問題:
問題是我無法將 firstName 和 lastName 分開。它就像一個搜索欄,您可以在其中將 firstName 和 lastName 放在同一個查詢中。這就是為什么我必須連接它們
有多種方法可以實作它。最好的方法是使用$text index和text search。我每天都在一個擁有 1 億多檔案的生產資料庫上使用它。
Mongoose 文本索引示例:
YourSchema.index(
{
'firstName': 'text',
'lastName': 'text',
},
{
weights:
{
'firstName': 2,
'lastName': 1
},
name: 'SearchQuery',
})
這是用于在多個欄位中搜索的文本索引的示例。但是,如果您想尋找Joe Doeas的組合,firstName & lastName您也可以使用虛擬欄位(不確定是否為 100%)或為文本索引添加一個單獨的欄位,例如:
集合模式
{
firstName: string,
lastName: string,
// combinedName: string
}
然后為combinedName欄位添加單獨的文本索引。
更新 v2
不幸的是,你不能在你的情況下使用貓鼬虛擬,最好的方法是firstLastName組合另一個欄位并添加一個具有適當權重的$text 查詢索引(它實際上支持語言和大小寫敏感搜索)到denomination和firstLastName欄位作為我上面描述過。
另一個相關但不是 MongoDB 的選項是將部分集合存盤在 ElasticSearch 中。
Is the only way to avoid performance issues for user-search queries (where reaction time is sensitive and should be no more then 2s) and without rebuilding the whole schema.
You could also make it possible, if you are using mongoose driver for mongo, with default property, where you could predefine your firstLastName value from this.lastName and this.lastName, so you won't need to manually add it every time.
But of course, for a first time, you'll need to update the whole connection via cursor:
await YourModel
.find()
.cursor()
//.sort(by proprery not sure)
.eachAsync(async (doc) => {
doc.firstLastName = `${doc.firstName} ${doc.lastName}`;
await doc.save();
})
or updateMany (but updateMany is long query and not so good controllable as cursor)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/335968.html
