【问题标题】:Java MongoDB ProjectionJava MongoDB 投影
【发布时间】:2020-08-18 10:55:23
【问题描述】:

我指的是 mongodb 官方页面进行投影,我遇到了以下示例,其中子文档中的数组元素被过滤: https://docs.mongodb.com/manual/reference/operator/aggregation/filter/#exp._S_filter

db.sales.aggregate([
   {
      $project: {
         items: {
            $filter: {
               input: "$items",
               as: "item",
               cond: { $gte: [ "$$item.price", 100 ] }
            }
         }
      }
   }
])

我正在尝试在 Java 中实现这一点,但我没有正确执行,并且子文档数组中的元素没有被过滤。

输入集合:

{
   _id: 0,
   items: [
     { item_id: 43, quantity: 2, price: 10 },
     { item_id: 2, quantity: 1, price: 240 }
   ]
}
{
   _id: 1,
   items: [
     { item_id: 23, quantity: 3, price: 110 },
     { item_id: 103, quantity: 4, price: 5 },
     { item_id: 38, quantity: 1, price: 300 }
   ]
}
{
    _id: 2,
    items: [
       { item_id: 4, quantity: 1, price: 23 }
    ]
}

预期输出集合:

{
   "_id" : 0,
   "items" : [
      { "item_id" : 2, "quantity" : 1, "price" : 240 }
   ]
}
{
   "_id" : 1,
   "items" : [
      { "item_id" : 23, "quantity" : 3, "price" : 110 },
      { "item_id" : 38, "quantity" : 1, "price" : 300 }
   ]
}
{ "_id" : 2, "items" : [ ] }

在 Java(mongo Driver 3.9.1)中,这就是我正在做的事情:

Bson priceFilter = Filters.gte("items.price", 100);
mongoCollection.aggregate(
  Aggregates.project(Projections.fields(priceFilter))
);

如何对需要根据某些条件从子文档数组中过滤掉元素的子文档数组使用聚合函数进行投影?

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework mongodb-java


    【解决方案1】:

    MongoDB Java Driver 3.9.1 中,collection.aggregate() 采用 java.util.List 作为参数。所以你需要用下面的代码替换你的Java代码。

    mongoCollection.aggregate(
                      Arrays.asList(
                                   Aggregates.project(Projections.computed("items",
                                        new Document().append("$filter",
                                                new Document().append("input", "$items").append("as", "item").append("cond", 
                                                         new Document().append("$gte",Arrays.asList("$$item.price",100))))))
                                  )
                       );
    

    【讨论】:

    • 感谢 RLD。此代码运行成功。如果文档中有更多字段,Aggregates.project 将删除它们。有没有办法让所有其他字段保持不变,因为文档也可能有几个其他字段。使用 Projections.include(String... fieldNames) 需要将每个文件都明确地放在这里。
    • 根据 MongoDB 文档docs.mongodb.com/manual/reference/operator/aggregation/project,要在输出文档中包含输入文档中的任何其他字段(“_id”字段除外),我们必须在 $project 中明确指定包含。所以我们必须在编码时做同样的事情,即我们必须使用 Projections.include(String... fieldNames)。如果它解决了您最初的问题,请接受我的回答。
    • 感谢 RLD。接受了你的回答。顺便说一句,MongoDB Compass 具有将聚合导出到 Java、Python 等语言的功能。:docs.mongodb.com/compass/current/export-pipeline-to-language 如果我们不想将所有字段显式添加到 Projection,我们可以使用带有过滤器的 $addFields,它应该有类似的对所有现有字段产生影响。
    • 谢谢哈米德。我必须检查你建议的 $addFields 选项。
    猜你喜欢
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 2015-02-01
    相关资源
    最近更新 更多