1

我的文件看起来是这样的:MongoDB的平均嵌入式阵列作为额外的字段

{ 
    "_id" : "53ce85eda2579da8b40c1f0f", 
    "name" : "Autokino", 
    "tags" : [ 
     "forMen" 
    ], 
    "ratings" : [ 
     { "rating" : 5, "uuid" : "..."}, 
     { "rating" : 4, "uuid" : "..."}, 
     { "rating" : 4, "uuid" : "..."}, 
     { "rating" : 1, "uuid" : "..."}, 
    ] 
} 

现在我需要ratings.rating的平均值(这里应该是3.5)。我的查询是这样的:

activities.aggregate([ 
    { $match: { _id: ObjectID(req.params.id) } }, 
    { $unwind: '$ratings' },                                           
    { $group: { 
     _id: '$_id', 
     rating: { $avg: '$ratings.rating'}, 
    }}, 
]); 

它的工作原理,但我得到的是:

{ 
    "_id" : "53ce85eda2579da8b40c1f0f", 
    "rating" : 3.5 
} 

,这就是我需要得到:

{ 
    "_id" : "53ce85eda2579da8b40c1f0f", 
    "name" : "Autokino", 
    "tags" : [ 
     "forMen" 
    ], 
    "rating" : 3.5 
} 

(原始文档而不评级阵列但随着等级的平均)

我怎样才能解决这个问题?

回答

3

$group$project流水线级的是,只有在声明的字段都发出“绝对”。这里需要另一个操作员。 $first会做:

activities.aggregate([ 
    { "$match": { "_id": ObjectID(req.params.id) } }, 
    { "$unwind": "$ratings" },                                           
    { "$group": { 
     "_id": "$_id", 
     "name": { "$first": "$name" }, 
     "tags": { "$first": "$tags" }, 
     "rating": { "$avg": "$ratings.rating" }, 
    }}, 
]); 

由于$unwind使得许多文件出的数组内容去规范化,您可以使用$first这里只取你是不是另有聚集更多的领域的“第一”的发生。

如果你担心许多领域的申报这样的MongoDB 2.6确实提供了$$ROOT变量。 I'ts用法和输出可能不是你真正想要的:

activities.aggregate([ 
    { "$match": { "_id": ObjectID(req.params.id) } }, 
    { "$project": { 
     "_id": "$$ROOT", 
     "ratings": 1 
    }}, 
    { "$unwind": "$ratings" },                                           
    { "$group": { 
     "_id": "$_id", 
     "rating": { "$avg": "$ratings.rating" }, 
    }}, 
]); 

这给了你这样的:

{ 
    "_id" : { 
     "_id": "53ce85eda2579da8b40c1f0f", 
     "name" : "Autokino", 
     "tags" : [ 
      "forMen" 
     ], 
     "ratings" : [ 
      { "rating" : 5, "uuid" : "..."}, 
      { "rating" : 4, "uuid" : "..."}, 
      { "rating" : 4, "uuid" : "..."}, 
      { "rating" : 1, "uuid" : "..."}, 
     ] 
    }, 
    "rating": 3.5 
} 

这是正常的,因为在这里通过_id分组相同总体上分组文件。所以你总是可以添加最后的$project以回到类似的状态。但是这里没有通配符。

+0

我的文档大,有许多领域,是有什么事,可以让我访问洞文件? – dkoch

+0

@dkoch在MongoDB中2.6存在$$ ROOT'变量,但将只分配给一个域,即使它是所有的文件在当前流水线阶段。你仍然需要一个最终的'$ project'来获得原始结构。无论如何,MongoDB查询都是数据结构。实际上应该生成它们而不是硬编码它们。 –

+0

开卷不起作用,因为$评级不会在第二个上市的投影 – dkoch

0

我只是通过这个整首歌曲和舞蹈也去了,最终有我所有的领域重新加回。不理想!

所以我刚刚发现这一点 - 要容易得多:我有一个评论阵列场,其中有1级住宅 - 5

{ 
     $addFields: { avg: { $avg: '$reviews.rating'}} 
},