Mongo嵌入式文档字段查询

时间:2020-11-12 18:08:17

标签: mongodb mongodb-query

我有一个与以下类似的文件的现有收藏集

{
    "_id" : UUID("ef2f3778-c74a-4a40-9169-a7798bc6c776"),
    "feedId" : UUID("677d0a5a-0ceb-43d9-954d-bfefddc22ca2"),
    "events" : {
        "1500" : {
            "t" : ISODate("2020-08-20T02:25:00.000Z"),
            "a" : {
                "Manager" : "Joe",
                "Amount" : 20.3
            }
        },
        "1800" : {
            "t" : ISODate("2020-08-20T02:30:00.000Z"),
            "a" : {
                "Manager" : "Joe",
                "Amount" : 21.3
            }
        },
        "2100" : {
            "t" : ISODate("2020-08-20T02:35:00.000Z"),
            "a" : {
                "Manager" : "Joe",
                "Amount" : 22.3
            }
        },
        "2400" : {
            "t" : ISODate("2020-08-20T02:40:00.000Z"),
            "a" : {
                "Manager" : "Joe",
                "Amount" : 23.3
            }
        }
    }
}

我对返回按时间顺序排列的所有“金额”字段值(“ t”字段)的查询感兴趣。现在,我认识到“事件”嵌入文档的结构不太可能正确构建。它应该是一个数组。但这恐怕是徒手的,即没有选择更改文档的选项。如何从集合中具有相同feedId的所有对象中返回类似于[20.3、21.3、22.3、23.3等]的查询?

编辑:我将添加事件对象/文档在每个集合对象上没有统一的名称。即在这里您将看到1500、1800、2100等。但是下一个文档可能只有1500和3000。

参考另一个有相同问题但似乎碰壁的帖子(未将文档架构更改为数组):

MongoDB Query Embedded Document Field

2 个答案:

答案 0 :(得分:1)

尝试此查询并检查是否符合您的预期要求(例如here

请注意,我已更改日期以方便阅读。

db.collection.aggregate([
  {
    "$match": {
      "feedId": 2
    }
  },
  {
    "$project": {
      "events": {
        "$objectToArray": "$events"
      }
    }
  },
  {
    "$unwind": "$events"
  },
  {
    "$sort": {
      "events.v.t": 1
    }
  },
  {
    "$group": {
      "_id": "$_id",
      "events": {
        "$push": "$events"
      }
    }
  },
  {
    "$addFields": {
      "count": "$events.v.a.Amount"
    }
  },
  {
    "$project": {
      "count": 1,
      "_id": 0
    }
  }
])

首先$matchfeedId字段,然后必须使用$objectToArray,因为您的架构由键值对象组成。
然后$unwind可以执行$sort并再次重新组合。
之后,我添加了一个新字段count,其中包含总额,并且我使用$project仅保留了该字段。

答案 1 :(得分:1)

@ J.F的回答使我接近。这是对我有用的查询:

db.collection.aggregate(
    [
        { $match: { feedId: 2 } },
        { $project: { events: {$objectToArray: "$events"} } },
        {
            "$unwind": "$events"
        },
        {
            "$sort": {
              "events.v.t": 1
            }
        },
        { $group: {  "_id": null, Amounts: { $push: "$events.v.a.Amount" } } },
        {
          "$project": {
            "Amounts": 1,
            "_id": 0
        }
      }
    ]
)

正在为我产生预期的结果。我希望它是正确的。

结果:

/* 1 */
{
    "Amounts" : [ 
        20.3, 
        21.3, 
        22.3, 
        23.3, 
        24.3, 
        25.3, 
        26.3, 
        27.3, 
        28.3, 
        29.3, 
        30.3, 
        31.3, 
        32.3, 
        33.3, 
        34.3, 
        35.3, 
        36.3, 
...

Example

相关问题