如何将聚合管道中的文档与MongoDB Java驱动程序3.6相结合?

时间:2018-02-05 16:28:46

标签: mongodb aggregation-framework mongodb-java

我正在使用MongoDB Java驱动程序版本3.6的聚合管道。如果我的文档看起来像:

doc1 -

{
  "CAR": {
    "VIN": "ASDF1234",
    "YEAR": "2018",
    "MAKE": "Honda",
    "MODEL": "Accord"
  },
  "FEATURES": [
    {
      "AUDIO": "MP3",
      "TIRES": "All Season",
      "BRAKES": "ABS"
    }
  ]
}

doc2 -

{
  "CAR": {
    "VIN": "ASDF1234",
    "AVAILABILITY": "In Stock"
  }
}

如果我提交的查询如下:

collection.aggregate(
    Arrays.asList(
        Aggregates.match(
            and(
                in("CAR.VIN", vinList),
                or(
                    eq("CAR.MAKE", carMake),
                    eq("CAR.AVAILABILITY", carAvailability),
                )
            )
        )
    )
)

让我们假设有两个不同的记录,其中" CAR.VIN"每个VIN的标准匹配,我将得到两个结果。我不是每次处理两个结果,而是想合并文档,以便结果如下:

{
  "CAR": {
    "VIN": "ASDF1234",
    "YEAR": "2018",
    "MAKE": "Honda",
    "MODEL": "Accord",
    "AVAILABILITY": "In Stock"
  },
  "FEATURES": [
    {
      "AUDIO": "MP3",
      "TIRES": "All Season",
      "BRAKES": "ABS"
    }
  ]
}

我有两个且只有两个结果的例子使我对此的需求变得微不足道。想象一下,vinList是10000个值的列表,它可能返回2 x 10000个文档。当我将AggregateIterable返回给调用我的代码的客户端时,我不想强​​制要求他们必须以任何方式对结果进行分组或整理,但是他们将为每个具有所有结果的结果收到一个文档。他们想要解析,干净,轻松的信息。

当然,人们会建议将数据简单地合并到一个包含MongoDB集合中所有数据的文档中。由于我无法控制的原因,有两个单独的文档对应于同一集合中的每个VIN,这是我无法更改的内容。我们的系统中有一个值使它比看起来更合理,所以请不要专注于这个明显的数据问题。

我正在努力利用Aggretes.group()操作来合并聚合管道中的字段。 Accumulators.push似乎是最接近我需要的操作,但我不想让文档结构与额外的数组等复杂化。是否有一种我没有看到的简单方法?

1 个答案:

答案 0 :(得分:0)

您可以尝试在mongo v3.6中添加$mergeObjects

db.cc.aggregate(
    [
        {
            $group: {
                _id : "$CAR.VIN", 
                CAR : {$mergeObjects : "$CAR"}, 
                FEATURES : {$mergeObjects : {$arrayElemAt : ["$FEATURES", 0 ]}}
            }
        }
    ]
).pretty()

结果

{
    "_id" : "ASDF1234",
    "CAR" : {
        "VIN" : "ASDF1234",
        "YEAR" : "2018",
        "MAKE" : "Honda",
        "MODEL" : "Accord",
        "AVAILABILITY" : "In Stock"
    },
    "FEATURES" : {
        "AUDIO" : "MP3",
        "TIRES" : "All Season",
        "BRAKES" : "ABS"
    }
}
> 

获取数组

的功能
db.cc.aggregate(
    [
        {
            $group: {
                _id : "$CAR.VIN", 
                CAR : {$mergeObjects : "$CAR"}, 
                FEATURES : {$push : {$arrayElemAt : ["$FEATURES", 0 ]}}
            }
        }
    ]
).pretty()

结果

{
    "_id" : "ASDF1234",
    "CAR" : {
        "VIN" : "ASDF1234",
        "YEAR" : "2018",
        "MAKE" : "Honda",
        "MODEL" : "Accord",
        "AVAILABILITY" : "In Stock"
    },
    "FEATURES" : [
        {
            "AUDIO" : "MP3",
            "TIRES" : "All Season",
            "BRAKES" : "ABS"
        },
        null
    ]
}
>