MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Requête de plage MongoDB sur toute la valeur du document intégré

Notez la commande quelques lignes plus bas dans la documentation que vous avez liée :

Cela vous indique que les champs inexistants et les champs définis sur null sont traités spécialement.

Dans l'ordre des documents {} et {a: null} pour être équivalent dans l'ordre de tri, l'algorithme de tri doit considérer que le champ de tri manquant est présent et avoir une valeur de null .

Si vous ajoutez explicitement le champ manquant, juste pour voir à quoi il ressemble, l'ordre a plus de sens.

Le filtre {tag: { $gte: { baz: MinKey() }}} appliqué à {_id: 1, tag: {bar: "BAR"}} compare essentiellement {baz: MinKey()} avec {baz: null, bar: "BAR"} .

Près du haut de la documentation que vous avez liée, il indique que MinKey est inférieur à null , c'est donc le bon ordre.

MODIFIER

En général, l'interrogation est plus efficace lorsque les noms de champs ne sont pas eux-mêmes des données. En termes de base de données tabulaire, quelle colonne contiendrait "baz" ?

Une légère modification du schéma simplifierait ce type de requête. Au lieu de {tagname: tagvalue} , utilisez {k:tagname, v:tagvalue} . Vous pourriez alors indexer tag.k et/ou tag.v , et requête sur tag.k pour trouver tous les documents avec une balise "baz", interroger les balises avec des opérations d'inégalité fonctionnerait de manière plus intuitive.

db.collection.find({"tag.k":{$gte:"baz"}})

Des correspondances exactes pourraient être faites avec elemMatch comme

db.collection.find({tag: {$elemMatch:{k:"baz",v:"BAZ"}}})

Si vous avez vraiment besoin que les documents renvoyés contiennent {tagname: tagvalue} , le $arrayToObject l'opérateur d'agrégation peut le faire :

db.collection.aggregate([
  {$match: {
      "tag.k": {$gte: "baz"}
  }},
  {
    $addFields: {
      tag: {$arrayToObject: [["$tag"]]}
  }}
])

Aire de jeux