Ich habe zwei Sammlungen. Die erste Sammlung enthält Studenten:
{ "_id" : ObjectId("51780f796ec4051a536015cf"), "name" : "John" }
{ "_id" : ObjectId("51780f796ec4051a536015d0"), "name" : "Sam" }
{ "_id" : ObjectId("51780f796ec4051a536015d1"), "name" : "Chris" }
{ "_id" : ObjectId("51780f796ec4051a536015d2"), "name" : "Joe" }
Die zweite Sammlung enthält Kurse:
{
"_id" : ObjectId("51780fb5c9c41825e3e21fc4"),
"name" : "CS 101",
"students" : [
ObjectId("51780f796ec4051a536015cf"),
ObjectId("51780f796ec4051a536015d0"),
ObjectId("51780f796ec4051a536015d2")
]
}
{
"_id" : ObjectId("51780fb5c9c41825e3e21fc5"),
"name" : "Literature",
"students" : [
ObjectId("51780f796ec4051a536015d0"),
ObjectId("51780f796ec4051a536015d0"),
ObjectId("51780f796ec4051a536015d2")
]
}
{
"_id" : ObjectId("51780fb5c9c41825e3e21fc6"),
"name" : "Physics",
"students" : [
ObjectId("51780f796ec4051a536015cf"),
ObjectId("51780f796ec4051a536015d0")
]
}
Jedes Kursdokument enthält ein students
Array mit einer Liste der für den Kurs registrierten Studenten. Wenn ein Student einen Kurs auf einer Webseite anzeigt, muss er prüfen, ob er sich bereits für den Kurs angemeldet hat oder nicht. Wenn die courses
Sammlung im Namen des Schülers abgefragt wird, müssen wir dazu herausfinden, ob das students
Array bereits die ObjectId des Schülers enthält. Gibt es eine Möglichkeit, in der Projektion einer Suchabfrage anzugeben, dass ein Schüler nur dann ObjectId
aus dem students
Array abgerufen werden soll, wenn er vorhanden ist?
Ich habe versucht zu sehen, ob ich den Operator $ elemMatch verwenden kann, aber er ist auf eine Reihe von Unterdokumenten ausgerichtet. Ich verstehe, dass ich ein Aggregationsframework verwenden könnte, aber es scheint, dass es in diesem Fall zu viel des Guten wäre. Das Aggregationsframework wäre wahrscheinlich nicht so schnell wie eine einzelne Suchabfrage. Gibt es eine Möglichkeit, die Kurssammlung abzufragen, damit das zurückgegebene Dokument eine ähnliche Form hat?
{
"_id" : ObjectId("51780fb5c9c41825e3e21fc4"),
"name" : "CS 101",
"students" : [
ObjectId("51780f796ec4051a536015d0"),
]
}
course
Sammlung besteht darin, dass Sie den Schülernamen an mehreren Stellen gespeichert haben, was möglicherweise zu einer Synchronisierung führen kann. In diesem Fall würde Ihre Abfrage unvollständige Daten zurückgeben. Wenn die Serverlast und die Hardware nicht sehr dünn sind, ist die zusätzliche Abfrage zum Abrufen des Namens möglicherweise vorzuziehen. Sie können weiterhin SchülerObjectId
als Objekt speichern, um die Abfrage des OP zuzulassen:{"id":...}
Es scheint, als würde der
$in
Betreiber Ihren Zwecken gut dienen.Sie könnten so etwas tun (Pseudo-Abfrage):
if (db.courses.find({"students" : {"$in" : [studentId]}, "course" : courseId }).count() > 0) { // student is enrolled in class }
Alternativ können Sie die
"course" : courseId
Klausel entfernen und eine Reihe aller Klassen zurückerhalten, in denen der Schüler eingeschrieben ist.quelle
Ich versuche es zu erklären, indem ich eine Problemstellung und eine Lösung dafür vorlege. Ich hoffe es wird helfen
Problemstellung:
Finden Sie alle veröffentlichten Produkte, deren Name wie ABC-Produkt oder PQR-Produkt lautet und deren Preis unter 15 / - liegen sollte.
Lösung:
Nachfolgend sind die Bedingungen aufgeführt, die berücksichtigt werden müssen
Unten finden Sie die Anweisung, die über dem oben genannten Kriterium zum Erstellen von Abfrage- und Abrufdaten gilt.
$elements = $collection->find( Array( [price] => Array( [$lt] => 15 ), [$or] => Array( [0]=>Array( [product_name]=>Array( [$in]=>Array( [0] => ABC Product, [1]=> PQR Product ) ) ) ), [state]=>Published ) );
quelle