【问题标题】:MongoDB aggregation: How to get the index of a document in a collection depending sorted by a document propertyMongoDB聚合:如何根据文档属性排序获取集合中文档的索引
【发布时间】:2020-12-14 14:10:51
【问题描述】:

假设我有一个包含数百万个文档的集合。以下是文档外观的示例

[
    { _id:"1a1", points:[2,3,5,6] },
    { _id:"1a2", points:[2,6] },
    { _id:"1a3", points:[3,5,6] },
    { _id:"1b1", points:[1,5,6] },
    { _id:"1c1", points:[5,6] },
    // ... more documents
]

我想通过_id查询一个文档并返回一个如下所示的文档:

{
    _id:"1a1",
    totalPoints: 16,
    rank: 29
}

我知道我可以查询整个文档,按降序排序,然后通过_id 获取我想要的文档的索引并添加一个以获得它的排名。但我担心这种方法。 如果文件数以百万计,这不会“过度”。查询整个集合只是为了获取一个文档?有没有办法在不查询整个集合的情况下实现我想要实现的目标?还是因为排名必须涉及整个收藏?

我无法保存他们的排名,因为分数一直在变化。实际代码更复杂,但我无法保存它们的排名。

总点数是点数组中点的总和。排名是通过按降序对所有文档进行排序来计算的。第一个文档成为排名 1,依此类推。

【问题讨论】:

  • 我正在查看更改流。看起来他们可以解决我的问题。
  • 排名是如何计算的?是按totalPoints排序后文档的位置吗?
  • @ĐĵΝιΓΞΗΛψΚ 是的。总点数是点数组中点的总和。排名是通过按降序对所有文档进行排序来计算的。第一个文档成为排名 1,依此类推。
  • 按降序获取它们,并使用.forEach加一个,如果id是你的id,则返回那个。
  • 我的问题不在于使用$group。我的问题是我想对集合中的所有文档进行排序并获取该集合中给定文档的索引。我是否必须查询所有文档进行排序并获取索引,或者是否有一种快捷方式不涉及查询所有文档只是为了获取一个?

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

像下面这样的聚合管道可以得到你想要的结果。但它如何处理数百万个文档的集合还有待观察。

db.collection.aggregate(
[
    {
        $group: {
            _id: null,
            docs: {
                $push: { _id: '$_id', totalPoints: { $sum: '$points' } }
            }
        }
    },
    {
        $unwind: '$docs'
    },
    {
        $replaceWith: '$docs'
    },
    {
        $sort: { totalPoints: -1 }
    },
    {
        $group: {
            _id: null,
            docs: { $push: '$$ROOT' }
        }
    },
    {
        $set: {
            docs: {
                $map: {
                    input: {
                        $filter: {
                            input: '$docs',
                            as: 'x',
                            cond: { $eq: ['$$x._id', '1a3'] }
                        }
                    },
                    as: 'xx',
                    in: {
                        _id: '$$xx._id',
                        totalPoints: '$$xx.totalPoints',
                        rank: {
                            $add: [{ $indexOfArray: ['$docs._id', '1a3'] }, 1]
                        }
                    }
                }
            }
        }
    },
    {
        $unwind: '$docs'
    },
    {
        $replaceWith: '$docs'
    }
])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 2019-01-17
    • 1970-01-01
    • 2023-01-31
    相关资源
    最近更新 更多