mongo 对数组的数据库查找查询到单个结果

mongo db lookup query on array into single result

我正在使用 $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"]
        }
    ]
}

我想这是指组还是因为unwind而不可能?我需要这样,所以我可以进一步将它处理成流星。

你是对的,你正在寻找 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 } }
]);

如果您不先 $unwind 原始文档,结果会更直接。 $lookup 能够直接从 "foreign keys" 的数组中查找,结果将已经是一个数组,避免了需要在之后有另一个 $unwind$group

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

如果您想将 Producttypes 转换为仅包含 offeringType 字段,您可以选择添加 { $addFields: {Producttypes: '$Producttypes.offeringType' } } }

我同意聚合是很棒的基本功能, 但有时它会让我们难以控制细小但具体的变化。

所以我在 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
  ]

希望对您有所帮助。