2017-10-16 2 views
0

Ich habe folgendes json Dokument in meiner Sammlung:MongoDB verschachtelte Abfragestruktur

{ 
    "_id": { 
     "$oid": "59e3a593734d1d62dcbe79c3" 
    } 
    "name": "UserNameKiran" 
    "notebooks": [ 
     { 
      "notebookname": "notebook1", 
      "notes": [ 
       { 
        "name": "noteName" 
       }, 
       { 
        "name": "noteName2" 
       } 
      ] 
     }, 
     { 
      "access": "public", 
      "notebookname": "notebook2", 
      "notes": [ 
       { 
        "name": "noteName" 
       }, 
       { 
        "name": "noteName2" 
       } 
      ] 
     } 
    ] 
}; 

Ich möchte von einem bestimmten Benutzer und Notebook alle „Notizen“ abzurufen. Beispiel: Alle Notizen für "notebook1".

Ich versuchte den folgenden Befehl, konnte aber kein Ergebnis erhalten.

req.db.collection('usernotecollection').find({ 
     "_id": ObjectId(req.params.userId), 
     "notebooks": { 
      "$elemMatch": { 
       "notebookname": "notebook1" 
      } 
     } 
    }, {notes:1}).toArray(function (err, results) { 
     console.log(results); 
    }); 

Es gibt mir nur die object_id und nichts anderes in den Ergebnissen. Was vermisse ich ?

Antwort

0

Der zweite Parameter, den Sie für den Anruf find() bereitstellen, lautet: {notes:1}.

Dies ist eine Projektion, es sagt MongoDB das Attribut mit dem Namen notes zurückzukehren, aber es gibt kein Attribut notes in Ihrem Dokument mit dem Namen, so dass nur die Projektion des Attributs Standardzurückgibt: _id.

Vielleicht wollten Sie stattdessen auf {notebooks:1} projizieren? Dies würde zwar alles zurückgeben und ist daher funktional gleichbedeutend mit der Bereitstellung einer Projektion.

Um dies deutlich zu machen, können Sie die folgenden Befehle ausführen können, und Sie werden sehen, dass sie beide die gleiche Antwort zurück:

req.db.collection('usernotecollection').find({ 
     "_id": ObjectId(req.params.userId), 
     "notebooks": { 
      "$elemMatch": { 
       "notebookname": "notebook1" 
      } 
     } 
    }).toArray(function (err, results) { 
     console.log(results); 
    }); 

req.db.collection('usernotecollection').find({ 
     "_id": ObjectId(req.params.userId), 
     "notebooks": { 
      "$elemMatch": { 
       "notebookname": "notebook1" 
      } 
     } 
    }, {notebooks:1}).toArray(function (err, results) { 
     console.log(results); 
    }); 

Wenn aber, was Sie wirklich wollen, ist das notes Attribut mit dem notebooks Sub-Dokumente dann möchten Sie auf 'notebooks.notes': 1 projizieren. Das folgende Beispiel-Projekte auf notebooks.notes und schließt die Projektion Standard _id dadurch nur Rückkehr notebooks.notes:

req.db.collection('usernotecollection').find({ 
     "_id": ObjectId(req.params.userId), 
     "notebooks": { 
      "$elemMatch": { 
       "notebookname": "notebook1" 
      } 
     } 
    }, {'notebooks.notes':1, '_id': 0}).toArray(function (err, results) { 
     console.log(results); 
    }); 
+0

Danke für die klare Erklärung. Ich bin jedoch nicht in der Lage, die Notizen eines bestimmten Notebooks zu erhalten. Aus irgendeinem Grund passiert die Übereinstimmung für "notebookname": "notebook1" nicht. –

+0

Tehre ist kein Attribut im Unterordner 'notebooks' mit dem Namen 'notebookname'. Vielleicht meinen Sie 'notes.name'. Im Allgemeinen werden Fragen dieser Form (_wie kann ich x aus diesem Dokument bekommen? _) Am besten mit (1) einem Beispieldokument gestellt; (2) ein Beispiel der Abfrage, die Sie versucht haben und (3) ** die gewünschte Ausgabe **. – glytching

+0

Danke Ich konnte mein Problem lösen –

0

Um die Array-Elemente filtern Sie den $elemMatch Operator in der Projektion Teil Ihrer Abfrage verwenden können.

req.db.collection('usernotecollection').find({ 
    // filter 
    "_id": ObjectId(req.params.userId) 
}, { 
    // projection 
    "notebooks": { 
     "$elemMatch": { 
      "notebookname": "notebook1" 
     } 
    } 
}).toArray(function (err, results) { 
    console.log(results); 
}); 
Verwandte Themen