在数组上的mongo db查找查询成单个结果

时间:2019-01-18 15:29:22

标签: mongodb meteor aggregation-framework lookup

我正在使用$ unwind执行查找查询,以便从一个集合的数组字段中找到所有与另一个集合相连的数组元素结果。我使用以下查询:

db.getCollection('Products').aggregate([{$unwind:"$SupplierOffers"},{$lookup:{from:"Offers", localField:"SupplierOffers",foreignField:"_id", as:"Producttypes"}},
{$project:{"Producttypes.offeringType":1, _id:1}}])

实际结果是

{
    "_id" : ObjectId("5bfe8978192b5c14e8d88ba7"),
    "Producttypes" : [ 
        {
            "offeringType" : "package A"
        }
    ]
}

{
    "_id" : ObjectId("5bfe8978192b5c14e8d88ba7"),
    "Producttypes" : [ 
        {
            "offeringType" : "package B"
        }
    ]
}

由于展开注释,是否可能有如下结果:

{
    "_id" : ObjectId("5bfe8978192b5c14e8d88ba7"),
    "Producttypes" : [ 
        {
            "offeringType" : ["package A","package B"]
        }
    ]
}

我想这是指组,或者由于展开是不可能的?我需要这种方式,所以我可以将其进一步处理成流星。

3 个答案:

答案 0 :(得分:1)

您正在寻找group是正确的。

尝试将其添加到管道中

{
  $group: {
    _id: '_id',
    offeringType: { $addToSet: '$Producttypes.offeringType' }
  }
}

编辑::这是评论中的后继查询,以供后代使用:

db.getCollection("Products").aggregate([
  {
    $unwind: "$SupplierOffers"
  },
  {
    $lookup: {
      from: "Offers",
      localField: "SupplierOffers",
      foreignField: "_id",
      as: "Producttypes"
    }
  },
  {
    $group: {
      _id: "$_id",
      offeringType: { $addToSet: "$Producttypes.offeringType" }
    }
  },
  { $sort: { _id: 1 } }
]);

答案 1 :(得分:1)

如果您不首先$unwind原始文档,这将变得更加简单。 $lookup可以直接从“外键”数组中查找,然后结果将已经是一个数组,从而避免了之后需要另外的$unwind$group

db.getCollection('Products').aggregate([
    { $lookup: {
        from:"Offers",        
        localField:"SupplierOffers", 
        foreignField:"_id", 
        as:"Producttypes" 
    }}
])

(可选)如果要将产品类型转换为仅包含offeringType字段,则可以添加{ $addFields: {Producttypes: '$Producttypes.offeringType' } } }

答案 2 :(得分:0)

我同意聚合是非常重要的功能, 但有时这使我们难以控制小而具体的更改。

因此,我建议在Meteor.js中使用类似以下内容的“ this.added”是一种无需聚合的好解决方案。

# Writing in Coffeescript
Meteor.publish 'pubName' ->
  cursor = Products.find()
  cursor.forEach (product) => #fat arrow for this binding
    #Play anything with product and the other collection's data
    product.Producttypes = Offers.findOne(_id: product.SupplierOffers)
    this.added('pubName', product._id, product) #The data binded to Products could be use in client
  return [
    cursor
    OtherCollection.find() #other collections to subscribe
  ]

希望这会有所帮助。