Il y a trop peu d'informations dans la question actuellement pour tirer des conclusions définitives. Comme @Tornike Skhulukhia suggère dans le commentaire en partageant l'intégralité .explain("executionStats")
pour cette agrégation nous donnerait beaucoup plus de visibilité sur ce qui peut se passer.
Une chose qui semble potentiellement suspecte ici, sur la base du peu qui a été partagé, est l'utilisation de crochets ( {
y }
) pour définir le pipeline
. Normalement, il s'agit d'un tableau permettant de prévoir une séquence d'étapes d'agrégation. En effet, mongoplayground se plaint lorsque des accolades sont utilisées. . Il s'agit probablement d'une erreur de copier/coller lors de la création de la question, d'autant plus qu'il y a la même faute de frappe avec l'attribut $in
mais il est certain que si le pilote/langage que vous utilisez n'a pas respecté la pipeline
jusqu'à la première étape qui peut aider à expliquer ce qui se passe. Notez qu'il est Il est possible, dans certaines situations, de transmettre un seul document (représentant l'unique étape d'agrégation) à la .aggregate()
elle-même plutôt qu'un tableau comme d'habitude, voici une petite démonstration de terrain de jeu prouvant qu'une telle structure y fonctionne avec succès. Des manigances de ce type ne sont donc pas à exclure et de plus amples informations seraient utiles.
Si je lis un peu entre les lignes, il semble que vous essayez d'améliorer les performances d'un pipeline d'agrégation. Bien que, encore une fois, il n'y ait pas assez d'informations pour affirmer quoi que ce soit avec certitude, je suggérerais de simplifier cette définition $lookup
. Votre stade actuel est défini comme suit :
{
"$lookup": {
"from": "metrics",
"as": "metrics",
"let": {
"userId": "$_id"
},
"pipeline": [
{
"$match": {
"$expr": {
"$in": [
"$$userId",
"$ownerIds"
]
}
}
},
{
"$project": {
"fieldName": 1,
"ownerIds": 1,
"auth0Cache": 1
}
}
],
}
}
Cela peut être simplifié en utilisant le localField
/ foreignField
syntaxe au moins comme suit :
{
"$lookup": {
"from": "metrics",
"as": "metrics",
localField: "_id",
foreignField: "ownerIds",
"pipeline": [
{
"$project": {
"fieldName": 1,
"ownerIds": 1,
"auth0Cache": 1
}
}
],
}
}
Démonstrations sur le terrain de jeu de avant y après .
Cette modification peut permettre à la base de données de mieux exploiter un indice de { ownerIds: 1 }
sur le metrics
collection.
La dernière chose que je mentionnerais est liée à l'utilisation de $project
. Il est vrai que c'est généralement une bonne idée de réduire la quantité de données traitées le plus tôt possible. Mais l'utilisation de la projection devrait être réservée à la fin d'un pipeline (ou sous-pipeline), juste comme un moyen de transformer les résultats dans le format que vous désirez. La base de données se chargera automatiquement de déterminer quels champs sont nécessaires au pipeline et limitera ces données de manière optimale chaque fois que cela sera possible.