【问题标题】:flatten objects of array mongodb $project展平数组 mongodb $project 的对象
【发布时间】:2019-04-17 20:13:35
【问题描述】:

我有一个名为患者的 mongodb 集合 - 包含数百个文档,其中每个文档代表 1 个人。每个文档都包含许多数组 - 其中一个数组表示有关患者的一类信息。此处的示例 - 显示根级别信息(_id、EnrollmentID)和 2 个数组:成像和健康状态。

/* 1 */
{
    "_id" : ObjectId("5be32372ca69786f080f36a1"),
    "EnrollmentId" : 1234,
    "imaging" : [
        {
            "EnrollmentId" : 1234,
            "CR_ImagingXRay" : "1 Time",
            "CR_ImagingCT" : "1 Time",
            "CR_ImagingMRI" : "1 Time",
        }
    ],
    "health_state" : [
        {
            "EnrollmentId" : 1234,
            "CR_DateAssessmentCompletion" : "14-Jan-16",
            "CR_HealthState" : 55.0
        },
        {
            "EnrollmentId" : 1234,
            "CR618_DateAssessmentCompletion" : "27-Apr-16",
            "CR618_HealthState" : NaN,
            "CR_CR618HealthStateChange" : NaN
        },
        {
            "EnrollmentId" : 1234,
            "CR12_DateAssessmentCompletion" : NaN,
            "CR12_HealthState" : NaN,
            "CR_CR12HealthStateChange" : NaN
        },
        {
            "EnrollmentId" : 1234,
            "CR24_DateAssessmentCompletion" : "8-Jan-18",
            "CR24_HealthState" : 85.0,
            "CR_CR24HealthStateChange" : 30.0
        }
    ]
}

我想使用聚合管道创建一个仅包含主文档特定元​​素的新文档。我写了这个查询:

db.patient.aggregate([
    {
        $project: 
            {_id: 0, EnrollmentId: 1,
             CR_HealthState: '$health_state.CR_HealthState',
             CR618_HealthState: '$health_state.CR618_HealthState',
             CR12_HealthState: '$health_state.CR12_HealthState',
             CR24_HealthState: '$health_state.CR24_HealthState'
            }},
   {
        $out: "test"
   }
   ])

这给出了这个输出:

/* 1 */
{
    "_id" : ObjectId("5bec716cb75cface16e9e88c"),
    "EnrollmentId" : 1234,
    "CR_HealthState" : [
        55.0
    ],
    "CR618_HealthState" : [
        NaN
    ],
    "CR12_HealthState" : [
        NaN
    ],
    "CR24_HealthState" : [
        85.0
    ]
}

我想要这样的“平面”输出:

/* 1 */
{
    "_id" : ObjectId("5bec716cb75cface16e9e88c"),
    "EnrollmentId" : 1234,
    "CR_HealthState" : 55.0,
    "CR618_HealthState" : NaN,
    "CR12_HealthState" : NaN,
    "CR24_HealthState" : 85.0
}

我是 mongodb 的新手 - 任何帮助都将不胜感激!

【问题讨论】:

  • 但它是一个数组!数组旨在存储“事物列表”。所以可以确保命名属性“发生”在所有元素中都是唯一的,您可以使用$mergeObjects“暴力破解”它,但实际上这只是糟糕的设计。如果您打算以这种方式访问​​数据,那么确实应该更改其存储方式的结构。那么你就不需要聚合管道语句来减慢速度了。
  • 我确实看到您正在尝试重组这些数据,但您的目的并不是那么明确。这里主要关注的是每个数组成员中清楚显示的一件事是"CR_DateAssessmentCompletion"。现在这些是不同的日期,使它们对“不同的条目”有效。您所要求的内容以一种因此没有多大意义的方式结合了不同日期的属性。至少这里的更多解释可能会让你的目的更清楚。

标签: mongodb


【解决方案1】:

由于您在数组中投影一个元素,因此投影本身就是一个数组,正如您所观察到的。为避免这种情况,您可以使用 $arrayElemAt 并引用数组的第一个元素,即 0 索引。见下文:

{'$project': {'EnrollmentId': 1,
             'CR_HealthState': {'$arrayElemAt': ['$health_state.CR_HealthState', 0]},
             'CR618_HealthState': {'$arrayElemAt': ['$health_state.CR618_HealthState', 0]},
             'CR12_HealthState': {'$arrayElemAt': ['$health_state.CR12_HealthState', 0]},
             'CR24_HealthState': {'$arrayElemAt': ['$health_state.CR24_HealthState', 0]},
            }},

【讨论】:

  • 这是完美的 - 正是我所追求的 - 谢谢。
猜你喜欢
  • 2021-12-25
  • 2015-02-25
  • 2021-12-29
  • 2017-04-06
  • 2017-05-13
  • 2018-02-24
  • 2015-05-23
  • 2023-01-11
  • 1970-01-01
相关资源
最近更新 更多