web-dev-qa-db-fra.com

Comment interroger des objets imbriqués?

J'ai un problème lors de l'interrogation de mongoDB avec la notation des objets imbriqués:

db.messages.find( { headers : { From: "[email protected]" } } ).count()
0
db.messages.find( { 'headers.From': "[email protected]" }  ).count()
5

Je ne vois pas ce que je fais mal. Je m'attends à ce que la notation d'objet imbriquée renvoie le même résultat que la requête de notation par points. Où est-ce que je me trompe?

183
Edmondo1984

db.messages.find( { headers : { From: "[email protected]" } } )

Ceci interroge les documents où headers est égal à { From: ... }, c’est-à-dire qu’il ne contient aucun autre champ.


db.messages.find( { 'headers.From': "[email protected]" } )

Ceci ne concerne que le champ headers.From, non affecté par les autres champs contenus dans ou manquant, headers.


docs de notation

369
shx2

Les deux mécanismes de requête fonctionnent de manière différente, comme suggéré dans les docs à la section Sous-documents :

Lorsque le champ contient un document incorporé (par exemple, sous-document ), vous pouvez spécifier le sous-document entier en tant que valeur d'un champ, ou "pénétrer" dans le sous-document à l'aide de la notation par points, pour spécifier les valeurs de champs individuels dans le champ. sous-document :

Correspondances d'égalité dans les sous-documents, sélectionnez des documents si le sous-document correspond exactement au sous-document spécifié, y compris l'ordre des champs.


Dans l'exemple suivant, la requête correspond à tous les documents où la valeur du producteur de champ est un sous-document contenant uniquement le champ company avec la valeur 'ABC123' et le champ address avec la valeur '123 Street', dans l'ordre exact:

db.inventory.find( {
    producer: {
        company: 'ABC123',
        address: '123 Street'
    }
});
19
Edmondo1984

Comme il y a beaucoup de confusion à propos de requêtes mongodb collection with sub-documents, j'ai jugé utile d'expliquer les réponses ci-dessus à l'aide d'exemples:

D'abord, j'ai inséré seulement deux objets dans la collection, à savoir: message comme:

> db.messages.find().pretty()
{
    "_id" : ObjectId("5cce8e417d2e7b3fe9c93c32"),
    "headers" : {
        "From" : "[email protected]"
    }
}
{
    "_id" : ObjectId("5cce8eb97d2e7b3fe9c93c33"),
    "headers" : {
        "From" : "[email protected]",
        "To" : "[email protected]"
    }
}
>

Alors, quel est le résultat de la requête: db.messages.find({headers: {From: "[email protected]"} }).count()

Il devrait être n parce que cette requête concerne des documents où headers est égal à l'objet {From: "[email protected]"}, c'est-à-dire qu'il ne contient aucun autre champ ou que nous devrions spécifier le sous-document entier comme valeur. d'un champ.

Donc, selon les années de @ Edmondo1984

Correspondances d'égalité dans les sous-documents sélectionner des documents si le sous-document correspond exactement le sous-document spécifié, y compris l'ordre des champs.

À partir des déclarations ci-dessus, quel est le résultat de la requête ci-dessous?

> db.messages.find({headers: {To: "[email protected]", From: "[email protected]"}  }).count()
0

Et si l’on changeait l’ordre de From et To c’est-à-dire les mêmes que les sous-documents des seconds documents?

> db.messages.find({headers: {From: "[email protected]", To: "[email protected]"}  }).count()
1

donc, il correspond exactement le sous-document spécifié, y compris l'ordre des champs.

Pour utiliser l’opérateur de point, je pense que c’est très clair pour tout le monde. Voyons le résultat de la requête ci-dessous:

> db.messages.find( { 'headers.From': "[email protected]" }  ).count()
2

Espérons que cette explication avec l'exemple éclaircira davantage recherche de requête avec sous-documents.

3
krishna Prasad