[英]MongoDB sort / weight $or aggregated query
我正在對數據庫中的兩個字段進行 $or 聚合查詢。 我希望第一個條件比第二個條件更相關,所以我想先對第一個條件匹配的條件進行排序,然后再返回后者。
這是一些代碼:
const regexp = new RegExp('^' + req.query.search, 'i')
const query = {
$or: [{ word: regexp }, { 'lang.english': regexp }],
}
const words = await collection
.find(query, {
collation: {
locale: 'sv',
strength: 1,
},
projection: {
'-_id': 1,
'word': 1,
'lang.english': 1,
'lang.definitionEnglish': 1,
'lang.definition': 1,
},
})
.skip(skips)
.limit(page_size)
.toArray()
所以基本上,那些匹配word
regexp 的結果應該首先出現,然后是lang.english
首先,讓我們將一些數據放入 MongoDB 測試集合中進行測試。
db.test.insertMany([
{ word: 'TEST123', lang: { english: 'wibble1' } },
{ word: 'wibble2', lang: { english: 'Test123' } },
{ word: 'test345', lang: { english: 'wibble3' } },
{ word: 'wibble4', lang: { english: 'testy101' } }
]);
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5f6924b271e546940acc10f7"),
ObjectId("5f6924b271e546940acc10f8"),
ObjectId("5f6924b271e546940acc10f9"),
ObjectId("5f6924b271e546940acc10fa")
]
}
這與問題中提到的結構相同。
接下來,我們可以構建一個聚合查詢,它將與您的 find 匹配,但這次附加一個我們可以排序的額外字段。 如果 word 字段匹配,我們將設置為 1,然后為其他任何設置設置為 2。
db.test.aggregate([
{ $match: { $or: [{ word: regexp }, { 'lang.english': regexp }] } },
{ $addFields: { sortingValue: { $cond: { if: { $regexMatch: { input: "$word" , regex: regexp } }, then: 1, else: 2 } } } }
]);
{
"_id" : ObjectId("5f6924b271e546940acc10f7"),
"word" : "TEST123",
"lang" : {
"english" : "wibble1"
},
"sortingValue" : 1
}
{
"_id" : ObjectId("5f6924b271e546940acc10f8"),
"word" : "wibble2",
"lang" : {
"english" : "Test123"
},
"sortingValue" : 2
}
{
"_id" : ObjectId("5f6924b271e546940acc10f9"),
"word" : "test345",
"lang" : {
"english" : "wibble3"
},
"sortingValue" : 1
}
{
"_id" : ObjectId("5f6924b271e546940acc10fa"),
"word" : "wibble4",
"lang" : {
"english" : "testy101"
},
"sortingValue" : 2
}
現在我們可以添加正常的排序、跳過和限制。
var regexp = new RegExp('^' + 'test', 'i')
var skip = 0;
var limit = 3;
db.test.aggregate([
{ $match: { $or: [{ word: regexp }, { 'lang.english': regexp }] } },
{ $addFields: { sortingValue: { $cond: { if: { $regexMatch: { input: "$word" , regex: regexp } }, then: 1, else: 2 } } } },
{ $sort: { sortingValue: 1 } },
{ $skip: skip },
{ $limit: limit }
]);
{
"_id" : ObjectId("5f6924b271e546940acc10f9"),
"word" : "test345",
"lang" : {
"english" : "wibble3"
},
"sortingValue" : 1
}
{
"_id" : ObjectId("5f6924b271e546940acc10f7"),
"word" : "TEST123",
"lang" : {
"english" : "wibble1"
},
"sortingValue" : 1
}
{
"_id" : ObjectId("5f6924b271e546940acc10f8"),
"word" : "wibble2",
"lang" : {
"english" : "Test123"
},
"sortingValue" : 2
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.