我正在尝试使用新的 AF 来迁移 Map/reduce。我有数百万个这样的对象:
{
_id: ObjectID,
owner: 1,
tags: [
{text: "dog", score: 5},
{text: "cat", score: 3},
{text: "hamster", score:1}]
}
{
_id: ObjectID,
owner: 2,
tags: [
{text: "cat", score: 8},
{text: "fish", score: 4}]
}
我想做一个报告,其中包含所有者为 X 的“cat”和“fish”的所有匹配项的计数。
到目前为止,我的管道假设输入标签 ["cat", "fish"] 看起来像:
{
$match: { owner: X, $in: {"tags.text": ["cat", "fish"]}}
}, {
$project: {text: "$tags.text"},
}, {
$unwind: "$text",
}, {
$match: {"text": {$in: {"tags": ["cat", "fish"]}}
}, {
$group: {"_id": "$text", "total: {"$sum": 1}}
}
第一个 $match 只是缩小到所有这百万个对象的子集 - 因为我有一个关于所有者和“tags.txt”的索引。
此管道对于少量标签运行良好,但我需要能够传递 100-1000 个“标签”并快速获得结果。似乎投影出并展开所有标签,而只是在下一个匹配步骤中过滤 90% 的标签,效率一定很低。
有没有更有效的方法?也许重新排列管道步骤?
最佳答案
这对我来说看起来不错,除了一些拼写错误以及每个 $match
管道操作中 $in
运算符的使用可能应该是:
{
$match: {owner: X, "tags.text": {$in: ["cat", "fish"]}}
}, {
$project: {text: "$tags.text"}
}, {
$unwind: "$text"
}, {
$match: {"text": {$in: ["cat", "fish"]}}
}, {
$group: {"_id": "$text", "total": {"$sum": 1}}
}
本质上,您希望在管道中尽早使用 $match
来限制管道中稍后处理的文档数量。 owner
和特定标签的匹配可以实现这一点。您还需要确保您的 $match
(相当于 .find()
)使用适当的索引。
关于mongodb - 使用 MongoDB 的新聚合框架搜索和计数标签的有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12514043/