首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >过滤嵌套对象

过滤嵌套对象
EN

Stack Overflow用户
提问于 2022-11-19 18:52:49
回答 2查看 32关注 0票数 1

我收集了一些类似的文档

代码语言:javascript
复制
{'id':1, 'score': 1, created_at: ISODate(...)}
{'id':1, 'score': 2, created_at: ISODate(...)}
{'id':2, 'score': 1, created_at: ISODate(...)}
{'id':2, 'score': 20, created_at: ISODate(...)}

等。

是否有人知道如何找到在过去24小时内创建的文档,其中同一id的最近两个文档之间的id值的差值小于5?

到目前为止,我只能找到在过去24小时内创建的所有文档:

代码语言:javascript
复制
[{
    $project: {
        _id: 0,
        score: 1,
        created_at: 1
    }
}, {
    $match: {
        $expr: {
            $gte: [
                '$created_at',
                {
                    $subtract: [
                        '$$NOW',
                        86400000
                    ]
                }
            ]
        }
    }
}]

任何建议都很感激。

编辑:通过两个最新的文档,其中最古老的一个可以在24小时前创建。因此,最近的文档将在过去的24小时内创建,但最老的文档可以在24小时前创建。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-19 21:08:24

如果我对你的理解是正确的,你想要的是:

代码语言:javascript
复制
db.collection.aggregate([
  {$match: {$expr: {$gte: ["$created_at", {$subtract: ["$$NOW", 86400000]}]}}},
  {$sort: {created_at: -1}},
  {$group: {_id: "$id", data: {$push: "$$ROOT"}}},
  {$project: {pair: {$slice: ["$data", 0, 2]}, scores: {$slice: ["$data.score", 0, 2]}}},
  {$match: {$expr: {
        $lte: [{$abs: {$subtract: [{$first: "$scores"}, {$last: "$scores"}]}}, 5]
  }}},
  {$unset: "scores"}
])

看看它如何在操场实例上工作

编辑:根据您的评论,一个选项是:

代码语言:javascript
复制
db.collection.aggregate([
  {$setWindowFields: {
      partitionBy: "$id",
      sortBy: {created_at: -1},
      output: {data: {$push: "$$ROOT", window: {documents: ["current", 1]}}}
  }},
  {$group: {
      _id: "$id",
      created_at: {$first: "$created_at"},
      pair: {$first: "$data"}
  }},
  {$match: {$expr: {$and: [
          {$gte: ["$created_at", {$dateAdd: {startDate: "$$NOW", unit: "day", amount: -1}},
          {$eq: [{$size: "$pair"}, 2]},
          {$lte: [{$abs: {$subtract: [{$first: "$pair.score"},
                    {$last: "$pair.score"}]}}, 5]}
  ]}}},
  {$project: {_id: 0, pair: 1}}
])

看看它如何在操场实例上工作

票数 1
EN

Stack Overflow用户

发布于 2022-11-19 20:59:20

如果我理解正确,您可以尝试以下查询:

  • 首先是$match,因为您必须从一天前就获得文档。
  • 然后,$sort的日期,以确保最近的是顶部。
  • $groupid,以及最近的是如何在顶部,使用$push将是数组中的第一个元素。
  • 所以现在您只需要$sum这两个值。
  • 再用这些小于($lt) 5的过滤器过滤。
代码语言:javascript
复制
db.collection.aggregate([
  {
    $match: {
      $expr: {
        $gte: [
          "$created_at",
          {
            $subtract: [
              "$$NOW",
              86400000
            ]
          }
        ]
      }
    }
  },
  {
    "$sort": {
      "created_at": -1
    }
  },
  {
    "$group": {
      "_id": "$id",
      "score": {
        "$push": "$score"
      }
    }
  },
  {
    "$project": {
      "score": {
        "$sum": {
          "$firstN": {
            "n": 2,
            "input": "$score"
          }
        }
      }
    }
  },
  {
    "$match": {
      "score": {
        "$lt": 5
      }
    }
  }
])

示例这里

编辑:$firstN是5.2版中的新版本。其他方式可以在$slice中使用这边请

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74502770

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档