我有一个Mongodb模式,大致如下:

[
  {
    "name" : "name1",
    "instances" : [ 
      {
        "value" : 1,
        "date" : ISODate("2015-03-04T00:00:00.000Z")            
      }, 
      {
        "value" : 2,
        "date" : ISODate("2015-04-01T00:00:00.000Z")
      }, 
      {
        "value" : 2.5,
        "date" : ISODate("2015-03-05T00:00:00.000Z")
      },
      ...
    ]
  },
  {
    "name" : "name2",
    "instances" : [ 
      ...
    ]
  }
]

其中每个元素的实例数量可能相当大.

我有时只想得到一个数据样本,也就是说,每三个实例,或者每十个实例...你明白了.

我可以通过获取所有实例并在服务器代码中过滤它们来实现这一目标,但我想知道是否有办法通过使用聚合查询来实现这一目标.

有什么 idea 吗?


Updated

假设数据 struct 是扁平的,如@SylvainLeroux建议的,即:

[
  {"name": "name1", "value": 1, "date": ISODate("2015-03-04T00:00:00.000Z")},
  {"name": "name2", "value": 5, "date": ISODate("2015-04-04T00:00:00.000Z")},
  {"name": "name1", "value": 2, "date": ISODate("2015-04-01T00:00:00.000Z")},
  {"name": "name1", "value": 2.5, "date": ISODate("2015-03-05T00:00:00.000Z")},
  ...
]

获得第n项(具体name项)的任务会更容易吗?

推荐答案

您可能喜欢使用$lookup聚合的这种方法.而且可能是最方便、最快捷的方式,而无需任何聚合技巧.

使用以下模式创建集合100

[
  { "_id": 1, "name": "name1" },
  { "_id": 2, "name": "name2" }
]

然后是父id为"nameId"100个集合

[
  { "nameId": 1, "value" : 1, "date" : ISODate("2015-03-04T00:00:00.000Z") },
  { "nameId": 1, "value" : 2, "date" : ISODate("2015-04-01T00:00:00.000Z") },
  { "nameId": 1, "value" : 3, "date" : ISODate("2015-03-05T00:00:00.000Z") },
  { "nameId": 2, "value" : 7, "date" : ISODate("2015-03-04T00:00:00.000Z") }, 
  { "nameId": 2, "value" : 8, "date" : ISODate("2015-04-01T00:00:00.000Z") }, 
  { "nameId": 2, "value" : 4, "date" : ISODate("2015-03-05T00:00:00.000Z") }
]

现在,使用$lookup聚合3.6语法,您可以在$lookup pipeline中使用$sample来随机获得每Nth个元素的值.

db.Names.aggregate([
  { "$lookup": {
    "from": Instances.collection.name,
    "let": { "nameId": "$_id" },
    "pipeline": [
      { "$match": { "$expr": { "$eq": ["$nameId", "$$nameId"] }}},
      { "$sample": { "size": N }}
    ],
    "as": "instances"
  }}
])

你可以测试here

Mongodb相关问答推荐

通过mongoDB中的查找从管道中删除被阻止的用户

如何使用聚合管道查找未销售但存在于产品详细信息集合中的产品的ID

如何在Mongo中查找数组中的特定对象

如何在 kubernetes 中获取分片 mongodb 的备份

更新值导致错误 Golang MongoDB

@DynamicPropertySource 未被调用(Kotlin、Spring Boot 和 TestContainers)

mongo:在 mongodb 6.0 docker 容器上找不到命令

根据聚合管道MongoDB Atlas触发器中的条件更新多个字段

MongoDB C# 驱动程序 - 如何将 _id 存储为 ObjectId 但映射到字符串 Id 属性?

Mongoose 架构引用和未定义类型ObjectID

Flask and Mongo

如何按季度分组日期?

Node + Mongoose:获取最后插入的 ID?

从每个组中 Select 前 N 行

在 mongodb 聚合框架中执行 case-statement

mongoose 使用 $cond 中的 $exists 聚合

Mongodb - 如何在多个字段中查找字符串?

MongoDB备份计划

Mongodb同时在多个字段上聚合(计数)

MongoDB Compass:select distinct field values