2014-09-01 6 views
0

Je veux obtenir toutes les valeurs correspondantes, en utilisant $ elemMatch.Comment rechercher un tableau intégré

// create test data 
db.foo.insert({values:[0,1,2,3,4,5,6,7,8,9]}) 
db.foo.find({},{ 
    'values':{ 
     '$elemMatch':{ 
      '$gt':3 
     } 
    } 
}) ; 

Mon résultat escompté est {values: [3,4,5,6,7,8,9]}. mais, vraiment résultat est {values: [4]}. Je lis le document mongo, je comprends que c'est la spécification.

Comment rechercher des valeurs multiples? Et plus, j'utilise 'skip' et 'limit'.

Une idée?

Répondre

1

Utilisation de l'agrégation:

db.foo.aggregate([ 
{$unwind:"$values"}, 
{$match:{"values":{$gt:3}}}, 
{$group:{"_id":"$_id","values":{$push:"$values"}}} 
]) 

Vous pouvez ajouter autre condition de filtre dans le match $, si vous le souhaitez.

Vous ne pouvez y parvenir en utilisant un opérateur elemMatch $ depuis, MongoDB doc dit:

L'opérateur de projection elemMatch $ limite le contenu d'un tableau champ qui est inclus dans les résultats de la requête pour contenir uniquement l'élément de tableau qui correspond à la condition $ elemMatch.

Remarque

The elements of the array are documents. 
+0

merci. Je considère à nouveau la structure de la collection. – sekitaka

0

Si vous regardez attentivement la documentation sur $elemMatch ou la contrepartie d'interroger l'opérateur positional $ vous verriez alors que seul le « premier » l'élément correspondant est renvoyé par ce type de "projection". Ce que vous cherchez est en réalité "manipulation" du contenu du document où vous voulez "filtrer" le contenu du tableau dans le document plutôt que de retourner l'élément original ou "apparié", car il ne peut y avoir qu'un seul rencontre.

Pour vrai « filtrage » vous avez besoin du cadre d'agrégation, car il y a plus de soutien là pour la manipulation de documents:

db.foo.aggregate([ 

    // No point selecting documents that do not match your condition 
    { "$match": { "values": { "$gt": 3 } } }, 

    // Unwind the array to de-normalize as documents 
    { "$unwind": "$values }, 

    // Match to "filter" the array 
    { "$match": { "values": { "$gt": 3 } } }, 

    // Group by to the array form 
    { "$group": { 
     "_id": "$_id", 
     "values": { "$push": "$values" } 
    }} 
]) 

Ou avec les versions modernes de MongoDB de 2.6 et au-delà, où les valeurs de tableau sont « uniques "vous pourriez faire ceci:

db.foo.aggregate([ 
    { "$project": { 
     "values": { 
      "$setDifference": [ 
       { "$map": { 
        "input": "$values", 
        "as": "el", 
        "in": { 
         "$cond": [ 
          { "$gt": [ "$$el", 3 ] }, 
          "$$el", 
          false 
         ] 
        } 
       }}, 
       [false] 
      ] 
     } 
    }} 
]) 
+0

merci. Je comprends comment utiliser '$ elemMatch'. Je considère à nouveau la structure de collecte. – sekitaka