【问题标题】:MongoDB group by array inner-elementsMongoDB按数组内部元素分组
【发布时间】:2014-02-25 20:35:37
【问题描述】:

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

_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"
]

我一直在尝试(未成功)根据过去 7 天内标记的文章数量获取所有艺术家 (class_artist) 的列表。

我已经做到了:

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});

但不幸的是,它不是根据单个数组值计算它们,而是根据数组组合(即艺术家列表)。

我尝试使用$unwind 函数,但未能成功。

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您使用的是什么框架?这不是 MongoDB shell,看起来像 MapReduce 周围的一些奇怪的包装器。在这种情况下,$unwind 将不可用,您需要它供aggregation framework 中的用户使用。这是你想要的 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 } }
    ])
    

    如此高效:

    1. Filter 按日期,因为您已经为过去 7 天设置了一个变量
    2. Project 只需要我们需要的字段{ 我们只需要一个! }
    3. Unwind 数组,所以我们现在对每个文档中的每个数组元素都有一个记录
    4. Group 来自扩展文档中的艺术家
    5. 投影成一种文档格式,您可以使用 _id 作为组乱用
    6. Sort 将结果倒序查看顶部标记的第一个

    聚合的好处在于您可以逐步建立这些阶段以查看发生了什么。

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

    【讨论】:

    猜你喜欢
    • 2021-12-20
    • 2021-12-22
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2021-05-14
    相关资源
    最近更新 更多