Mongodb: la Requête de la taille des tableaux imbriqués

0

La question

J'ai le Schéma suivant:

Schema({
caller_address: {
    type: String,
    required: true,
},
traces: [[{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Call',
}]]

});

Et je tiens à le récupérer uniquement les objets qui ont des traces avec les Appels d'un montant supérieur à un nombre déterminé. En d'autres termes, la taille d'au moins un tableau imbriqué de traces doit être plus grand qu'un nombre spécifié. Je suis en train d'utiliser $elemMatch et $taille, mais sans succès. Pour l'instant, j'ai ce code:

CallerTraces.find({ 'traces' : { $elemMatch: { $size : { $gt: minTraceSize } }}})

Où minTraceSize est un int.

Pourriez-vous les gars m'aider? Je voudrais vraiment l'apprécier!

arrays mongodb nested
2021-11-23 20:27:28
1

La meilleure réponse

0

Merci pour l'échantillon de données. Ma réponse sera un cru MQL solution, pas une mangouste solution, donc une traduction sera nécessaire.

J'ai pu insérer deux documents en fonction de vos commentaires dans votre post. J'ai dû changer l'ObjectId de l'un des deux exemples de documents parce que vos échantillons ont la même valeur de clé primaire et génère un double de la clé d'exception.

Insérer Des Données D'Exemple

db.CallerTraces.insert(
{
  "_id": ObjectId("6175e7ecc62cff004462d4a6"),
  "traces": [
    [
      ObjectId("6175e7ecc62cff004462d4a4")
    ]
  ],
  "caller_address": "0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990"
})


db.CallerTraces.insert(
{
  "_id": ObjectId("6175e7ecc62cff004462d4a7"),
  "traces": [
    [
      ObjectId("6175e7ecc62cff004462d4a4"),
      ObjectId("6175e7ecc62cff004462d4a4")
    ],
    [
      ObjectId("6175e7ecc62cff004462d4a4")
    ]
  ],
  "caller_address": "0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990"
})

Si je veux trouver des enregistrements ayant plus de 0 éléments dans le tableau traces Je peux émettre les éléments suivants:

Trouver plus de zéro traces

db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 0 ] } })

Cela renvoie les éléments suivants:

Enterprise replSet [primary] barrydb> db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 0 ] } })
[
  {
    _id: ObjectId("6175e7ecc62cff004462d4a6"),
    traces: [ [ ObjectId("6175e7ecc62cff004462d4a4") ] ],
    caller_address: '0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990'
  },
  {
    _id: ObjectId("6175e7ecc62cff004462d4a7"),
    traces: [
      [
        ObjectId("6175e7ecc62cff004462d4a4"),
        ObjectId("6175e7ecc62cff004462d4a4")
      ],
      [ ObjectId("6175e7ecc62cff004462d4a4") ]
    ],
    caller_address: '0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990'
  }
]

Trouver plus de 1 trace

Si, au contraire, je veux trouver plus d'une trace, j'ai simplement modifier la requête légèrement:

db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 1 ] } })

... et cela revient avec les résultats suivants:

Enterprise replSet [primary] barrydb> db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 1 ] } })
[
  {
    _id: ObjectId("6175e7ecc62cff004462d4a7"),
    traces: [
      [
        ObjectId("6175e7ecc62cff004462d4a4"),
        ObjectId("6175e7ecc62cff004462d4a4")
      ],
      [ ObjectId("6175e7ecc62cff004462d4a4") ]
    ],
    caller_address: '0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990'
  }
]

Conclusion

Lors de la tentative d'évaluer la longueur du tableau dans le processeur de requêtes, nous devons choisir d'utiliser l' $eval option que la syntaxe pour MQL n'a pas d'examiner votre cas d'utilisation. L' $eval est un peu un fourre-tout option pour des choses qui ne rentrent pas bien dans le MQL cadre.

Mise à JOUR #1 OP introduit des exigences supplémentaires. Plutôt que de regarder le comte de la matrice, nous devons considérer le comte de la matrice dans la matrice (imbriquée à l'intérieur de tableau). Depuis la méthode find() avec $expr ne peut pas évaluer les tableaux imbriqués nous devons plutôt utiliser l'agrégation de cadre et de se détendre à l'extérieur de la matrice. Cet exemple les magasins de la forme originale dans un nouveau champ appelé original puis remplace la racine après l'ensemble de l'évaluation est terminée. Depuis déroulement peut entraîner des doublons dans le pipeline, nous finaliser $avec un groupe pour supprimer les doublons.

Solution

db.CallerTraces.aggregate([
    {
        $addFields: {
            "original._id": "$_id",
            "original.traces": "$traces",
            "original.caller_address": "$caller_address"
        }
    },
    {
        $unwind: "$traces"
    },
    {
        $match: { $expr: { $gt: [ { $size: "$traces" }, 1 ] } }
    },
    {
        $replaceRoot: { newRoot: "$original" }
    },
    {
        $group:
        {
            _id: "$_id",
            traces: { "$first": "$traces" },
            caller_address: { "$first": "$caller_address" }
        }
    }
])
2021-11-24 21:42:44

Bonjour, je vous Remercie pour votre réponse rapide! Mais n'est pas encore tout à fait le problème... je veux obtenir les Traces de tailles dans le deuxième niveau d'imbrication. Donc, si j'ai: { "_id": ObjectId("6175e7ecc62cff004462d4a7"), "traces": [ [ ObjectId("6175e7ecc62cff004462d4a4"), ObjectId("6175e7ecc62cff004462d4a4") ] ], "caller_address": "0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990" }), Cet objet doit retourner lorsque j'ai mis les 2 à la minTraceSize variable.
Bruno Medeiros

@BrunoMedeiros - s'il vous plaît voir les mises à jour dans mon post.
barrypicker

il a travaillé! Merci beaucoup! =)
Bruno Medeiros

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................