Étant donné le tableau [4,7,90,1]
ce que vous voulez dans votre requête est ceci :
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 } }
])
Donc, ce que cela fait, pour chaque élément contenu dans ce $or
condition, le user_id
le champ est testé par rapport à la valeur fournie, et $eq
renvoie 1
ou 0
pour true
ou false
.
Ce que vous faites dans votre code est pour chaque élément que vous avez dans le tableau que vous créez la condition de tableau de $or
. Il s'agit donc simplement de créer une structure de hachage pour chaque condition égale, de la transmettre à un tableau et de la brancher comme valeur de tableau pour le $or
état.
J'aurais probablement dû laisser l'opérateur $cond en dehors du code précédent pour que cette partie soit plus claire.
Voici du code pour le 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 } }
]
Si vous souhaitez avoir des pondérations individuelles et que nous supposerons des paires clé-valeur, vous devez imbriquer avec $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 } }
])
Notez qu'il ne s'agit que d'une valeur de retour, celles-ci n'ont pas besoin d'être dans l'ordre. Et vous pouvez penser à la génération de cela.
Pour générer cette structure voir ici :
https://stackoverflow.com/a/22213246/2313887