, ограничивает элементы массива документа! Это было очень странно!

рассмотренияэта страницаименно этот запрос

db.scores.find(
   { results: { $elemMatch: { $gte: 80, $lt: 85 } } }
)

Я использовал следующий импорт

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;

И придумал следующий код для выполнения аналогичной операции (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);

Для фильтрации документов, имеющих следующую структуру

{
    "_id": {
        "$oid": "588899721bbabc26865f41cc"
    },
    "userId": 55,
    "myArray": [
        {
            "id": "5888998e1bbabc26865f41d2",
            "title": "ABC"
        },
        {
            "id": "5888aaf41bbabc3200e252aa",
            "title": "ABC"
        }
    ]
}

Но вместо того, чтобы получить один или нет предмета изmyArray поле, я всегда получаю оба предмета!

Единственный код, который работал для меня, следующий

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);

Так почему же первый фрагмент кода, который должен вести себя так же, как запрос, показанный в начале вопроса, а не фильтровать результаты, как ожидалось?

Мне не нужно «агрегировать» результаты, мне нужно «фильтровать» их, используя идентификатор пользователя и идентификатор элемента массива.

Ответы на вопрос(1)

Ваш ответ на вопрос