MongoDB由数组内部元素组成

Gil*_*rim 38 mongodb mongodb-query aggregation-framework

我有一个文章列表,每个文章都有一个数组属性,列出了其中提到的各个人:

_id: {
    $oid: "52b632a9e4f2ba13c82ccd23"
},
providerName: "The Guardian",
url: "http://feeds.theguardian.com/c/34708/f/663860/s/3516cebc/sc/38/l/0L0Stheguardian0N0Cmusic0C20A130Cdec0C220Cwaterboys0Efishermans0Eblues0Etour0Ehammersmith/story01.htm",
subject: "The Waterboys – review",
class_artist: [
    "paul mccartney"
]
Run Code Online (Sandbox Code Playgroud)

我一直在努力(不成功)class_artist根据他们在过去7天内被标记的文章数量来获取所有个体艺术家的列表().

我已经达到了:

var date = new Date();
date.setDate(date.getDate() - 7);

db.articles.group({
    key: { class_artist: 1 },
    cond: { class_date: { $gt: date } },
    reduce: function ( curr, result ) { result.cnt++; },
    initial: { cnt : 0 }
}).sort({cnt: -1});
Run Code Online (Sandbox Code Playgroud)

但不幸的是,它并不是基于单个数组值来计算它们,而是基于数组合成(即艺术家列表).

我尝试使用该$unwind功能,但无法使其工作.

Nei*_*unn 117

你使用什么框架?这不是MongoDB shell,看起来像MapReduce的一些奇怪的包装.在这种情况下,$ unwind将不可用,您需要在聚合框架中为用户使用它.这是你想要的mongo shell:

db.articles.aggregate([
  {$match: { class_date: { $gte: date } } },
  {$project: { _id: 0, class_artist: 1 } },
  {$unwind: "$class_artist" },
  {$group: { _id: "$class_artist", tags: { $sum: 1 } }},
  {$project: { _id: 0,class_artist: "$_id", tags: 1 } },
  {$sort: { tags: -1 } }
])
Run Code Online (Sandbox Code Playgroud)

如此有效:

  1. 按日期过滤,因为您已经为过去7天设置了var
  2. 项目只有场(S),我们需要{我们只需要一个!}
  3. 放松数组,所以我们现在有一个记录每一个文档中的每个数组元素
  4. 从扩展文档中对艺术家进行分组
  5. 将项目转换为文档格式,您可以将其用作与_id混淆的组
  6. 相反的顺序对结果进行排序,以便首先查看标记的顶部

关于聚合的好处是你可以逐步建立这些阶段以查看正在发生的事情.

根据需要摇动并烘焙到您自己的驱动程序实现或ODM框架中.

  • 仅供参考,该"怪异包装"格式是[`组()`命令(http://docs.mongodb.org/manual/reference/command/group/),其在JavaScript中实现,并且早于聚合框架.参见:[MongoDB的聚合的比较:组(),$组和MapReduce](http://stackoverflow.com/questions/12337319). (3认同)