L'agrégation de filtre après $recherche
Comment puis-je ajouter un filtre après un $recherche ou est-il une autre méthode pour faire cela?
Ma collecte de données de test est:
{ "_id" : ObjectId("570557d4094a4514fc1291d6"), "id" : 100, "value" : "0", "contain" : [ ] }
{ "_id" : ObjectId("570557d4094a4514fc1291d7"), "id" : 110, "value" : "1", "contain" : [ 100 ] }
{ "_id" : ObjectId("570557d4094a4514fc1291d8"), "id" : 120, "value" : "1", "contain" : [ 100 ] }
{ "_id" : ObjectId("570557d4094a4514fc1291d9"), "id" : 121, "value" : "2", "contain" : [ 100, 120 ] }
Je select id 100 et globale de l'enfant:
db.test.aggregate([ {
$match : {
id: 100
}
}, {
$lookup : {
from : "test",
localField : "id",
foreignField : "contain",
as : "childs"
}
}]);
Je serai de retour:
{
"_id":ObjectId("570557d4094a4514fc1291d6"),
"id":100,
"value":"0",
"contain":[ ],
"childs":[ {
"_id":ObjectId("570557d4094a4514fc1291d7"),
"id":110,
"value":"1",
"contain":[ 100 ]
},
{
"_id":ObjectId("570557d4094a4514fc1291d8"),
"id":120,
"value":"1",
"contain":[ 100 ]
},
{
"_id":ObjectId("570557d4094a4514fc1291d9"),
"id":121,
"value":"2",
"contain":[ 100, 120 ]
}
]
}
Mais je veux seulement childs qui correspondent avec la valeur: 1"
À la fin je m'attends à ce résultat:
{
"_id":ObjectId("570557d4094a4514fc1291d6"),
"id":100,
"value":"0",
"contain":[ ],
"childs":[ {
"_id":ObjectId("570557d4094a4514fc1291d7"),
"id":110,
"value":"1",
"contain":[ 100 ]
},
{
"_id":ObjectId("570557d4094a4514fc1291d8"),
"id":120,
"value":"1",
"contain":[ 100 ]
}
]
}
OriginalL'auteur Phillip Bartschinski | 2016-04-06
Vous devez vous connecter pour publier un commentaire.
La question ici est en fait quelque chose de différent et n'a pas besoin de
$recherche
à tous. Mais pour toute personne arrivant ici purement dans le titre de "filtrage après $recherche", alors ce sont les techniques pour vous:MongoDB 3.6 - Sous-pipeline
Plus tôt de dollars en recherche + $détendez-vous + $match coalescence
Si vous la question, pourquoi voulez-vous
$détendez-vous
par opposition à l'aide$filter
sur le tableau, puis lire Somme globale de recherche Total de la taille des documents dans la correspondance de pipeline dépasse la taille de document maximale pour tous les détails sur pourquoi cela est généralement nécessaire et bien plus optimale.Pour les rejets de MongoDB, 3.6 et versions ultérieures, alors le plus expressif de "sous-pipeline" est généralement ce que vous voulez pour "filtrer" les résultats de la collecte à l'étranger avant toute chose revient dans le tableau.
Retour à la réponse, mais qui, en fait, explique pourquoi la question posée besoins "aucune jointure"....
Original
À l'aide de
$recherche
comme ce n'est pas la plus "efficace" façon de faire ce que vous voulez ici. Mais plus sur cela plus tard.Comme un concept de base, il suffit d'utiliser
$filter
sur le tableau résultant:Ou de l'utilisation
$éditer
à la place:À la fois obtenir le même résultat:
Ligne de fond est que
$recherche
lui-même ne peut pas "encore" requête pour sélectionner uniquement certaines données. Donc tous les "filtrage" qui doit arriver après la$recherche
Mais vraiment pour ce type d ' "auto-jointure" vous êtes mieux de ne pas utiliser
$recherche
à tous et d'éviter la surcharge d'un supplément de lire et de "hash-fusion" entièrement. Extraire seulement les éléments connexes et$group
à la place:Qui vient seulement de sortir un peu différent parce que j'ai volontairement enlevé le superflu et de champs. Ajoutez-les à vous-même si vous voulez vraiment:
Donc, la seule question ici est de "filtrage" tout
null
résultat de la matrice, créés lorsque le document actuel est laparent
dans le traitement des éléments de$push
.Ce que vous semblez aussi manque ici, c'est que le résultat que vous recherchez n'a pas besoin d'agrégation ou de "sous-requêtes". La structure que vous avez conclu ou peut-être trouvé ailleurs est "conçu", de sorte que vous pouvez obtenir un "nœud" et tous ses "enfants" en une seule requête.
Cela signifie que la "requête" est tout ce qui est vraiment nécessaire, et la collecte de données ( qui est tout ce qui se passe car aucun contenu n'est vraiment "réduit" ) n'est qu'une fonction d'itération le curseur de résultat:
Cela fait exactement la même chose:
Et sert de preuve que tout ce que vous devez faire ici est question de la "simple" requête pour sélectionner à la fois le parent et les enfants. Les données retournées sont les mêmes, et tout ce que vous faites soit sur le serveur ou le client est "massage" dans un autre recueillies format.
C'est l'un de ces cas où vous pouvez obtenir "capturé" dans la pensée de la façon dont on fait les choses dans une "relationnelle" de la base de données, sans se rendre compte que, depuis la façon dont les données sont stockées a "changé", vous n'avez plus besoin d'utiliser la même approche.
C'est exactement ce que le point de la documentation exemple "Arbre du Modèle des Structures de l'Enfant Références" dans sa structure, où il est facile de sélectionner les parents et les enfants dans une seule requête.
En termes de "performance", puis
$lookup
est en fait un "deux" des requêtes, mais sur le "serveur". Le "client" peut faire "les deux" les requêtes, mais bien sûr il y a du réseau et de la réponse que les coûts qui va ralentir le processus. C'est pourquoi vous ne$lookup
. Mais je suis aussi dire que votre cas n'a pas besoin de cela. Tous les éléments sont déjà dans la même collection, de sorte qu'il suffit de les sélectionner et de$group
en conséquence. En termes de "performance" qui est de loin la meilleure option de trois.Je pense que vous êtes toujours coincé dans le "relationnel de la pensée", ici, qui est de vous faire penser à "sous-requête" ou "auto-jointure" quand en fait, vous n'avez ni besoin. Ajout de la pure "pas d'agrégation" la méthode ici de le démontrer.
Oui je suis nouveau à l'orientation du document sujet et chercher quelles sont les différences. Je vais essayer plus tard et regardez comment je peux construire ma structure complexe. mais merci pour l'instant
OriginalL'auteur Neil Lunn