嵌套数组最常见元素查询及Poem文档says最高计数字符查询求助
解决Poem集合的两个查询需求:角色台词统计与嵌套数组高频元素
首先我先假设你的Poem文档结构大概是这样的(如果和实际结构有出入,你可以对应调整字段名):
{ "_id": ObjectId("60d21b4667d0d8992e610c85"), "title": "The Raven", "lines": [ { "character": "Narrator", "says": "Once upon a midnight dreary..." }, { "character": "Raven", "says": "Nevermore" }, { "character": "Raven", "says": "Nevermore" }, { "character": "Narrator", "says": "Quoth the raven..." } ], "themes": ["gothic", "melancholy", "loss"] // 示例嵌套数组字段 }
一、查找每首诗中says计数最高的角色
我们可以用MongoDB的聚合管道来实现这个需求,核心思路是先拆分台词数组、统计每个角色的台词数,再找出每首诗里的最高值:
db.poems.aggregate([ // 1. 拆分每首诗的lines数组,让每条记录对应一句台词 { $unwind: "$lines" }, // 2. 按诗ID和角色分组,统计该角色在这首诗里的台词数量 { $group: { _id: { poemId: "$_id", character: "$lines.character" }, lineCount: { $sum: 1 }, title: { $first: "$title" } // 保留诗的标题方便查看 } }, // 3. 重新按诗ID分组,把同一首诗的所有角色统计结果收集到数组中 { $group: { _id: "$_id.poemId", title: { $first: "$title" }, characterStats: { $push: { character: "$_id.character", lineCount: "$lineCount" } } } }, // 4. 筛选出每首诗里台词数最多的角色(如果有多个角色计数相同,取第一个) { $addFields: { topCharacter: { $arrayElemAt: [ { $filter: { input: "$characterStats", cond: { $eq: ["$$this.lineCount", { $max: "$characterStats.lineCount" }] } } }, 0 ] } } }, // 5. 整理输出格式,只保留需要的字段 { $project: { _id: 0, poemId: "$_id", title: 1, topCharacter: 1 } } ])
关键步骤解释:
$unwind: 把数组拆分成独立的文档,方便后续统计每个角色的台词数- 第一次
$group: 统计单个角色在单首诗中的台词总量 - 第二次
$group: 把同一首诗的所有角色统计结果聚合到一起,方便后续找最大值 $max+$filter: 先找出所有角色中的最高台词数,再筛选出对应这个数值的角色
二、统计嵌套数组中最常见的元素
这个需求分两种场景,我都给你提供解决方案:
场景1:全局范围内最常见的元素(所有诗的嵌套数组合并统计)
比如统计所有诗的themes数组里出现次数最多的主题:
db.poems.aggregate([ // 1. 拆分嵌套数组(把你的实际字段名替换掉`themes`) { $unwind: "$themes" }, // 2. 按数组元素分组,统计出现次数 { $group: { _id: "$themes", occurrenceCount: { $sum: 1 } } }, // 3. 按出现次数降序排序,次数相同则按元素名称排序 { $sort: { occurrenceCount: -1, _id: 1 } }, // 4. 可选:只取前5个最常见的元素 { $limit: 5 }, // 5. 整理输出格式 { $project: { _id: 0, element: "$_id", occurrenceCount: 1 } } ])
场景2:每首诗自己的嵌套数组中最常见的元素
如果需要单独统计每首诗里的高频元素,逻辑和第一个问题类似:
db.poems.aggregate([ // 1. 拆分嵌套数组 { $unwind: "$themes" }, // 2. 按诗ID和数组元素分组,统计该元素在这首诗里的出现次数 { $group: { _id: { poemId: "$_id", element: "$themes" }, count: { $sum: 1 }, title: { $first: "$title" } } }, // 3. 按诗ID分组,收集所有元素的统计结果 { $group: { _id: "$_id.poemId", title: { $first: "$title" }, elementStats: { $push: { element: "$_id.element", count: "$count" } } } }, // 4. 找出每首诗里出现次数最多的元素 { $addFields: { mostCommonElement: { $arrayElemAt: [ { $filter: { input: "$elementStats", cond: { $eq: ["$$this.count", { $max: "$elementStats.count" }] } } }, 0 ] } } }, // 5. 整理输出格式 { $project: { _id: 0, poemId: "$_id", title: 1, mostCommonElement: 1 } } ])
内容的提问来源于stack exchange,提问作者Konstantin Chsherbakov
相关产品推荐
相关产品推荐

