java - 使用 MongoDB Java 驱动程序组合多个数组进行查询

标签 java mongodb aggregation-framework mongo-java-driver

我有以下 JSON:

{"pid":"b00l16vp","categories":{"category1":["factual", "arts culture and the media", "history"]}}
{"pid":"b0079mpp","categories":{"category2":["childrens", "entertainment and comedy", "animation"],"category1":["signed"]}}
{“pid":"b00htbn3"}
{“pid":"b00gdhqw","categories":{"category2":["factual"],"category3":["scotland"],"category4":["lifestyle and leisure", "food and drink"],"category1":["entertainment", "games and quizzes"]}}

我的目的是通过将所有数组组合在一个数组中,使用字符串数组来查询类别对象。 我有以下代码:

String [] cats = ["childrens", "signed"]
BasicDBObject theProjections = new BasicDBObject()
for (int i = 1; i <= 5; i++) {
    String identifier = "categories.category" + i
    String cleanIdentifier = "\$" + identifier
    //If the category does not exist, put in a blank category
    def temp = [cleanIdentifier, []]
    theMegaArray.add(new BasicDBObject('$ifNull', temp))
}
//The megaArray is the array created in the above loop which combines all arrays
BasicDBObject theData = new BasicDBObject('$setUnion', theMegaArray)
BasicDBObject theFilter = new BasicDBObject('input', theData)
theFilter.put("as", "megaArray")
//all of the values found in cats should match the megaArray
theFilter.put("cond", new BasicDBObject('$all', ["\$\$megaArray", cats]))
theProjections.put('$filter', theFilter)
FindIterable iterable = collection.find(criteria).projection(theProjections)

我用过this到目前为止编写这段代码的问题。 $setUnion期望所有字段都会出现,但是在我的 JSON 中,有不同数量的类别数组,因此我使用了 $ifNull用 [] 填充空类别。 $filter已用于查询 megaArray 上的 cats 数组。

运行此程序时,我收到以下错误:

Caused by: com.mongodb.MongoQueryException: Query failed with error code 2 and error message '>1 field in obj: { input: { $setUnion: [ { $ifNull: [ "$categories.category1", [] ] }, { $ifNull: [ "$categories.category2", [] ] }, { $ifNull: [ "$categories.category3", [] ] }, { $ifNull: [ "$categories.category4", [] ] }, { $ifNull: [ "$categories.category5", [] ] } ] }, as: "megaArray", cond: { $all: [ "$$megaArray", [ "factual" ] ] } }'

我不完全确定这意味着什么,因为看起来是正确的。我还应该注意,类别对象并不总是存在,但我不确定这是否重要。

最佳答案

您可以使用聚合框架获得相同的结果

为此,您可以首先投影数据以创建“megaArray”,然后与新数组进行匹配。

String [] cats = new String[] {"childrens", "signed"};

List<DBObject> theMegaArray = new ArrayList<>();

BasicDBObject theProjections = new BasicDBObject();

for (int i = 1; i <= 5; i++) {
  String identifier = "categories.category" + i;
  String cleanIdentifier = "$" + identifier;
  //If the category does not exist, put in a blank category
  Object[] temp = new Object[] {cleanIdentifier, new Object[]{}};
  theMegaArray.add(new BasicDBObject("$ifNull", temp));
}

theProjections.put("_id", 1);
theProjections.put("pid", 1);
theProjections.put("categories",1);
theProjections.put("allCategories", new BasicDBObject("$setUnion", theMegaArray));

BasicDBObject theFilter = new BasicDBObject("allCategories", new BasicDBObject("$all", cats));

List<BasicDBObject> pipeline = new ArrayList<>();
pipeline.add(new BasicDBObject("$project", theProjections));
pipeline.add(new BasicDBObject("$match", theFilter));

AggregateIterable iterable = collection.aggregate(pipeline);

上面的代码示例在项目阶段添加了一个名为“allCategories”的新数组,然后与这个新文档进行匹配。

可以添加另一个投影阶段以从最终输出中删除 allCategories 数组

关于java - 使用 MongoDB Java 驱动程序组合多个数组进行查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44051789/

相关文章:

java - Java与小程序之间的通信

mongodb - 如何在聚合管道 mongodb 中使用 $update/$set 运算符?

mongodb - 如何为多个数据中心设置 MongoDB?

node.js - mongodb 的 $project 是否有可能返回一个数组?

MongoDB嵌套对象聚合计数

MongoDB 聚合 - 使用另一个数组过滤数组

java - 单击按钮时选择方法

Java,对构成有向图的节点 ArrayList 执行深拷贝

java - 评估 JSTL 中的 list.contains 字符串

mongodb - 带有express和mongoDB的NodeJS应用程序