MongoDB中统计全组合词对及获取LiciList项关联方法咨询
统计MongoDB中LiciList项的词对关联关系
嘿,我来帮你搞定这个问题!先假设你的文档结构大概是这样的(如果实际结构有差异,你可以调整后续的聚合逻辑):
{ "_id": ObjectId("60d21b4667d0d8992e610c85"), "LiciList": ["苹果", "香蕉", "橙子"], // 其他字段... }
下面分两种常见场景来实现词对统计:
场景1:统计同一文档内词的共现关联
如果你的需求是:同一LiciList数组里的词属于同一上下文,要统计这些词两两共同出现的频次(比如"苹果-香蕉"在多少个文档里同时出现),可以用以下聚合管道:
db.your_collection.aggregate([ // 1. 生成当前文档内所有不重复的两两词对(避免A-B和B-A重复统计) { $project: { pairs: { $map: { input: { $range: [0, { $size: "$LiciList" }] }, as: "i", in: { $map: { input: { $range: [{ $add: ["$$i", 1] }, { $size: "$LiciList" }] }, as: "j", in: { word1: { $arrayElemAt: ["$LiciList", "$$i"] }, word2: { $arrayElemAt: ["$LiciList", "$$j"] } } } } } }, _id: 0 } }, // 2. 把嵌套的词对数组展开成单个文档 { $unwind: "$pairs" }, { $unwind: "$pairs" }, // 3. 组合成统一格式的词对(方便分组) { $project: { word_pair: { $concat: ["$pairs.word1", "-", "$pairs.word2"] } } }, // 4. 按词对分组,统计共现次数 { $group: { _id: "$word_pair", co_occurrence_count: { $sum: 1 } } }, // 可选:按频次从高到低排序 { $sort: { co_occurrence_count: -1 } } ])
关键逻辑说明:
- 用
$range和$map生成数组内的两两组合,j从i+1开始,确保每个词对只生成一次(不会出现"香蕉-苹果"重复统计"苹果-香蕉"的情况) - 如果需要区分词对顺序(比如"苹果-香蕉"和"香蕉-苹果"算不同关联),把
$range的起始值改成0即可,同时去掉$add: ["$$i", 1]的限制
场景2:统计跨文档的词关联(全局词对频次)
如果你的需求是:统计所有文档中,任意两个词共同出现的总次数(不管是不是在同一个文档里),可以用自连接的方式实现:
db.your_collection.aggregate([ // 1. 展开LiciList数组,每个词单独成文档 { $unwind: "$LiciList" }, // 2. 自连接集合,获取所有包含当前词的文档 { $lookup: { from: "your_collection", // 替换成你的集合名称 localField: "LiciList", foreignField: "LiciList", as: "related_docs" } }, // 3. 展开关联文档的LiciList数组 { $unwind: "$related_docs" }, { $unwind: "$related_docs.LiciList" }, // 4. 过滤掉相同词和重复词对 { $match: { $expr: { $lt: ["$LiciList", "$related_docs.LiciList"] } } }, // 5. 组合词对格式 { $project: { word_pair: { $concat: ["$LiciList", "-", "$related_docs.LiciList"] }, _id: 0 } }, // 6. 分组统计总频次 { $group: { _id: "$word_pair", total_count: { $sum: 1 } } }, // 可选:按频次排序 { $sort: { total_count: -1 } } ])
关键优化建议:
- 如果数据量较大,给
LiciList字段创建索引:db.your_collection.createIndex({ LiciList: 1 }),能大幅提升$lookup的性能 - 如果存在大小写差异(比如"Apple"和"apple"),可以在
$unwind后用$toLower统一转换:{ $addFields: { LiciList: { $toLower: "$LiciList" } } }
内容的提问来源于stack exchange,提问作者Gabriel Sartori
相关产品推荐
相关产品推荐

