Givet arrayet [4,7,90,1]
hvad du ønsker i din forespørgsel er dette:
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 } }
])
Så hvad det gør, er for hvert element indeholdt i den $or
betingelse, user_id
feltet testes mod den angivne værdi og $eq
returnerer 1
eller 0
for true
eller false
.
Det, du gør i din kode, er for hvert element, du har i det array, du bygger matrixtilstanden for $or
. Så det er bare at skabe en hash-struktur for hver lig-betingelse, sende den til en matrix og tilslutte den som matrixværdien for $or
tilstand.
Jeg burde nok have udeladt $cond-operatoren fra den forrige kode, så denne del ville have været klarere.
Her er noget kode til 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 } }
]
Hvis du vil have individuelle vægte, og vi antager nøgleværdipar, skal du indlejre med $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 } }
])
Bemærk at det kun er en returværdi, disse behøver ikke at være i orden. Og du kan tænke på genereringen af det.
For at generere denne struktur se her:
https://stackoverflow.com/a/22213246/2313887