Nach this page, speziell diese AbfrageWie filtert man Dokumente basierend auf einem eingebetteten Array?
db.scores.find(
{ results: { $elemMatch: { $gte: 80, $lt: 85 } } }
)
Überprüfung verwendete ich die folgenden Importe
import static com.mongodb.client.model.Filters.and;
import static com.mongodb.client.model.Filters.elemMatch;
import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Projections.excludeId;
import static com.mongodb.client.model.Projections.fields;
import static com.mongodb.client.model.Projections.include;
und kam mit dem folgenden Code, um eine ähnliche Operation (ARRAY_FIELD_NAME = "myArray"
)
MongoCollection<Document> collection = mongoDB.getCollection(COLLECTION_NAME);
Bson filters = and(eq("userId", userId), elemMatch(ARRAY_FIELD_NAME, eq("id", id)));
Bson projections = fields(include(ARRAY_FIELD_NAME), excludeId());
List<Document> results = (List<Document>) collection.find(filters).projection(projections).first().get(ARRAY_FIELD_NAME);
if (CollectionUtils.isEmpty(results)) {
return null;
}
if (results.size() > 1) {
throw new ApiException(String.format("Multiple results matched (User ID: %s, Array item ID: %s)", userId, id));
}
return results.get(0);
auszuführen
So filtern Sie Dokumente mit der folgenden Struktur
{
"_id": {
"$oid": "588899721bbabc26865f41cc"
},
"userId": 55,
"myArray": [
{
"id": "5888998e1bbabc26865f41d2",
"title": "ABC"
},
{
"id": "5888aaf41bbabc3200e252aa",
"title": "ABC"
}
]
}
Aber statt ein einzelnes oder kein Element aus dem Feld myArray
bekomme ich immer beide Elemente!
Der einzige Code, der für mich gearbeitet wird folgende
MongoCollection<Document> collection = mongoDB.getCollection(COLLECTION_NAME);
List<Bson> aggregationFlags = new ArrayList<>();
aggregationFlags.add(new Document("$unwind", "$" + ARRAY_FIELD_NAME));
aggregationFlags.add(new Document("$match", new Document("userId", userId).append(ARRAY_FIELD_NAME + ".id", id)));
aggregationFlags.add(new Document("$project", new Document("_id", 0).append(ARRAY_FIELD_NAME, "$" + ARRAY_FIELD_NAME)));
return (Document) collection.aggregate(aggregationFlags).first().get(ARRAY_FIELD_NAME);
Also, warum der Code nicht das erste Stück, das das gleiche wie die Abfrage zu Beginn der Frage gezeigt verhalten sollte, nicht Ergebnisse filtert wie erwartet ?
Ich muss nicht Ergebnisse "aggregieren", ich muss sie "filtern" mit der Benutzer-ID und Array-Element-ID.
Zuerst konnte ich nicht sehen, wie Ihre Antworten mein Problem ansprechen. Aber ich habe die "elemMatch" -Dokumentation für Projektionen und Filter gelesen und erst jetzt verstehe ich. 'Filters.elemMatch' filtert die Dokumente mit dem passenden Array-Filter. Während 'Projections.elemMatch', begrenzt die Array-Elemente des Dokuments! Das war sehr verwirrend! –