Gegeven de array [4,7,90,1]
wat je wilt in je zoekopdracht is dit:
db.collection.aggregate([
{ "$project": {
"user_id": 1,
"content": 1,
"date": 1,
"weight": { "$or": [
{ "$eq": ["$user_id": 4] },
{ "$eq": ["$user_id": 7] },
{ "$eq": ["$user_id": 90] },
{ "$eq": ["$user_id": 1] },
]}
}},
{ "$sort": { "weight": -1, "date": -1 } }
])
Dus wat dat doet is, voor elk item in die $or
voorwaarde, de user_id
veld wordt getest tegen de opgegeven waarde, en $eq
retourneert 1
of 0
voor true
of false
.
Wat u in uw code doet, is voor elk item dat u in de array heeft die u bouwt de arrayvoorwaarde van $or
. Dus het maakt gewoon een hash-structuur voor elke is gelijk aan voorwaarde, geeft deze door aan een array en plugt die in als de array-waarde voor de $or
staat.
Ik had waarschijnlijk de $cond-operator uit de vorige code moeten laten, zodat dit deel duidelijker zou zijn geweest.
Hier is wat code voor de Ruby Brain:
userList = [4, 7, 90, 1];
orCond = [];
userList.each do |userId|
orCond.push({ '$eq' => [ 'user_id', userId ] })
end
pipeline = [
{ '$project' => {
'user_id' => 1,
'content' => 1,
'date' => 1,
'weight' => { '$or' => orCond }
}},
{ '$sort' => { 'weight' => -1, 'date' => -1 } }
]
Als u individuele gewichten wilt hebben en we nemen sleutelwaardeparen aan, dan moet u nesten met $cond :
db.collection.aggregate([
{ "$project": {
"user_id": 1,
"content": 1,
"date": 1,
"weight": { "$cond": [
{ "$eq": ["$user_id": 4] },
10,
{ "$cond": [
{ "$eq": ["$user_id": 7] },
9,
{ "$cond": [
{ "$eq": ["$user_id": 90] },
7,
{ "$cond": [
{ "$eq": ["$user_id": 1] },
8,
0
]}
]}
]}
]}
}},
{ "$sort": { "weight": -1, "date": -1 } }
])
Merk op dat het slechts een retourwaarde is, deze hoeven niet in orde te zijn. En je kunt nadenken over de generatie daarvan.
Voor het genereren van deze structuur zie hier:
https://stackoverflow.com/a/22213246/2313887