mongoose 如何使用MongoDB聚合来只获取那些索引可被5整除的记录?

brvekthn  于 2023-06-30  发布在  Go
关注(0)|答案(1)|浏览(112)

下面是我的数据在名为usages的集合中的样子:

{ _id: AUTOGENERATED_MONGO_OBJECT_ID, timeStamp: 1675122960, usage: null, limit: 2.7 },
{ _id: AUTOGENERATED_MONGO_OBJECT_ID, timeStamp: 1675123020, usage: 2.74, limit: 2.7 },
{ _id: AUTOGENERATED_MONGO_OBJECT_ID, timeStamp: 1675123080, usage: 2.62, limit: 2.7 },
{ _id: AUTOGENERATED_MONGO_OBJECT_ID, timeStamp: 1675123140, usage: 4.32, limit: 2.7 },
{ _id: AUTOGENERATED_MONGO_OBJECT_ID, timeStamp: 1675123200, usage: null, limit: 2.7 },
{ _id: AUTOGENERATED_MONGO_OBJECT_ID, timeStamp: 1675123260, usage: 5.38, limit: 2.7 },
{ _id: AUTOGENERATED_MONGO_OBJECT_ID, timeStamp: 1675123320, usage: 5.08, limit: 2.7 },
{ _id: AUTOGENERATED_MONGO_OBJECT_ID, timeStamp: 1675123380, usage: 1.02, limit: 2.7 },
{ _id: AUTOGENERATED_MONGO_OBJECT_ID, timeStamp: 1675123440, usage: 2.35, limit: 2.7 },

**请注意:**这只是我的数据看起来的示例,实际上,我有40000条记录。

我尝试使用以下mongoose查询获取最后60条数据记录:

const count = await Usage.count()
  Usage.find({}).sort({ timeStamp: 1 }).skip(count - 60);

到目前为止,一切都运行良好。
但是现在,需要在所需范围内获得更少的数据。让我们说输出只需要有12个记录从最后60个记录,而不会丢失太多的数据。我们将使用这些数据在前端绘制折线图。
所以,我可以过滤数据,这样我就可以选择索引可被5整除的数据。
下面是我的代码:

const count = await Usage.count();
    const data = await Usage
        .find({})
        .sort({ timeStamp: 1 })
        .skip(count - start)
        .exec();
    const requiredData = data.filter((item, index) => index % 5 === 0);
    console.log(requiredData);

上面的代码应该按预期工作,但它是非常缓慢的,因为我过滤数据后,我从数据库中得到它。
理想情况下,我应该使用一些查询过滤数据,因此数据库应该只给予我过滤后的结果。
有人能帮我实现这一点吗?
这里有一个非常相似的问题:filter Items of Array by Index in Aggregation Pipeline
但是在这个问题中,OP希望根据名为arr的特定字段进行过滤。但在我的情况下,我想根据整个集合进行过滤。我不太了解如何使用聚合来编写查询。我尝试了一些视频教程来学习聚合,但它看起来有点复杂,需要更多的时间来学习它。

bpsygsoo

bpsygsoo1#

试试这个:

db.collection.aggregate([
   { $sort: { t: -1 } },
   { $limit: 60 },
   {
      $setWindowFields: {
         sortBy: { t: 1 },
         output: {
            pos: { $documentNumber: {} }
         }
      }
   },
   { $set: { remainder: { $mod: ["$pos", 5] } } },
   { $match: { remainder: 1 } },
   { $sort: { t: 1 } },
   { $unset: ["pos", "remainder"] }
])

Mongo Playground
使用$setWindowFields,您可以做得更高级,例如,如果与前一个文档的差异小于xyz,则跳过该文档。

相关问题