Come interrogare oggetti nidificati?


204

Ho un problema durante l'interrogazione di mongoDB con notazione di oggetti nidificati:

db.messages.find( { headers : { From: "reservations@marriott.com" } } ).count()
0
db.messages.find( { 'headers.From': "reservations@marriott.com" }  ).count()
5

Non riesco a vedere cosa sto facendo di sbagliato. Mi aspetto che la notazione oggetto nidificato restituisca lo stesso risultato della query di notazione punto. Dove sbaglio?

Risposte:


419

db.messages.find( { headers : { From: "reservations@marriott.com" } } )

Questa ricerca di documenti dove è headers uguale { From: ... } , cioè non contiene altri campi.


db.messages.find( { 'headers.From': "reservations@marriott.com" } )

Questo esamina solo il headers.Fromcampo, non influenzato da altri campi contenuti o mancanti da headers.


Documenti con notazione a punti


Esiste un modo per farlo senza le virgolette intorno a "headers.From"?
trysis

Non lo so, mi chiedo solo e ho pensato che a volte potesse essere utile.
trysis

3
@trysis - In pratica, ho scoperto che dichiarare oggetti inline (come gli esempi nei documenti mongo [ose] e nella maggior parte degli esempi là fuori) semplicemente non è abbastanza nel mondo reale. Ho sviluppato l'abitudine di creare oggetti 'condizioni' e 'campi' su cui posso fare cose come conditions['some.path'] = 'value'nella mia logica aziendale, quindi eseguire una singola query alla fine:find(conditions, fields, callback);
Ryan Wheale

Che cosa succede se andiamo dicono che ho una chiave che contiene "domain.com", questo non funzionerà: domains.domain.com. Esistono soluzioni alternative per questo scenario (senza modificare domain.com in qualcos'altro, ad esempio domain_com)?
Rens Tillmann,

1
Rispondendo al mio commento, è meglio evitare di usare completamente i punti nelle chiavi. Nella mia soluzione ho completamente abbandonato i domini essendo chiavi, e invece ho creato una slice / array.
Rens Tillmann,

20

I due meccanismi di query funzionano in modi diversi, come suggerito nei documenti nella sezione Documenti secondari :

Quando il campo contiene un documento incorporato (ovvero documento secondario ), è possibile specificare l'intero documento secondario come valore di un campo oppure "raggiungere" il documento secondario utilizzando la notazione punto, per specificare i valori per i singoli campi nel documento secondario :

Le corrispondenze di uguaglianza all'interno dei documenti secondari selezionano i documenti se il documento secondario corrisponde esattamente al documento secondario specificato, incluso l'ordine dei campi.


Nel seguente esempio, la query corrisponde a tutti i documenti in cui il valore del produttore del campo è un documento secondario che contiene solo il campo companycon il valore 'ABC123'e il campo addresscon il valore '123 Street', nell'ordine esatto:

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

8
Stavo impazzendo. Questo mi sembra abbastanza incoerente, perché quando si interrogano oggetti è possibile abbinare le proprietà dirette in qualsiasi ordine.
Capaj,

7

Dato che c'è molta confusione riguardo alle query sulla raccolta MongoDB con documenti secondari , ho pensato che valesse la pena spiegare le risposte sopra con esempi:

Innanzitutto ho inserito solo due oggetti nella collezione e precisamente: messagecome:

> db.messages.find().pretty()
{
    "_id" : ObjectId("5cce8e417d2e7b3fe9c93c32"),
    "headers" : {
        "From" : "reservations@marriott.com"
    }
}
{
    "_id" : ObjectId("5cce8eb97d2e7b3fe9c93c33"),
    "headers" : {
        "From" : "reservations@marriott.com",
        "To" : "kprasad.iitd@gmail.com"
    }
}
>

Quindi qual è il risultato della query: db.messages.find({headers: {From: "reservations@marriott.com"} }).count()

Dovrebbe essere uno perché queste query per documenti erano headersuguali all'oggetto {From: "reservations@marriott.com"}, cioè non contengono altri campi o dovremmo specificare l'intero sotto-documento come valore di un campo.

Come per la risposta di @ Edmondo1984

Le corrispondenze di uguaglianza all'interno dei documenti secondari selezionano i documenti se il documento secondario corrisponde esattamente al documento secondario specificato, incluso l'ordine dei campi .

Dalle affermazioni precedenti, quale dovrebbe essere il risultato della query di seguito?

> db.messages.find({headers: {To: "kprasad.iitd@gmail.com", From: "reservations@marriott.com"}  }).count()
0

E se cambiassimo l'ordine Frome Tocioè lo stesso dei sottodocumenti dei secondi documenti?

> db.messages.find({headers: {From: "reservations@marriott.com", To: "kprasad.iitd@gmail.com"}  }).count()
1

quindi, corrisponde esattamente al documento secondario specificato, incluso l'ordine dei campi .

Per l'utilizzo dell'operatore punto, penso che sia molto chiaro per tutti. Vediamo il risultato della query seguente:

> db.messages.find( { 'headers.From': "reservations@marriott.com" }  ).count()
2

Spero che queste spiegazioni con l'esempio di cui sopra rendano qualcuno più chiaro nel trovare query con documenti secondari .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.