如何基于嵌入式数组过滤文档? [英] How to filter documents based on an embedded array?

查看:126
本文介绍了如何基于嵌入式数组过滤文档?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看此页面,特别是此查询

After reviewing this page, specifically this query

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

And came up with the following code to perform a similar 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);

过滤具有以下结构的文档

To filter documents that have the following structure

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

但我始终不会同时从myArray字段中获得任何物品,而是得到所有物品!

But instead of getting a single or no item from the myArray field, I always get both items !

唯一适用于我的代码如下

The only code that worked for me is the following

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

那么为什么第一部分代码的行为应与问题开头所示的查询相同,而不是按预期过滤结果?

So why does the first piece of code that should behave the same as the query shown at the beginning of the question, not filter results as expected ?

我不需要汇总"结果,我需要使用用户ID和数组项ID过滤"它们.

I do not need to "aggregate" results, I need to "filter" them using the user ID and array item id.

推荐答案

您需要使用

You need to use $elemMatch(projection). Something like below should work.

import static com.mongodb.client.model.Projections.elemMatch;

Bson filters = and(eq("userId", userId));
Bson projections = fields(elemMatch(ARRAY_FIELD_NAME, eq("id", id)), excludeId());

这篇关于如何基于嵌入式数组过滤文档?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆