在mongo中投射子查询



我使用动态表单构建器将值存储到mongo中。这意味着字段在运行时定义。

现在我试图让用户构建数据的动态网格视图,以便他们可以选择他们想要看一眼字段。因此,我需要投影存储在集合项中的字段子集。

下面是集合

中2条记录的示例
{
"_id": {
    "$oid": "511ff0a8521e66d41b0d35d6"
},
"FormID": {
    "$uuid": "413ba627-94bf-0ca7-49b3-9ca2a1a3e9b5"
},
"ResultID": {
    "$uuid": "45f455ae-8486-aaa9-b97a-e480bfdf3db4"
},
"FieldValues": [
    {
        "FieldID": "first name",
        "FieldValue": "John"
    },
    {
        "FieldID": "last name",
        "FieldValue": "smith"
    },
    {
        "FieldID": "school",
        "FieldValue": "high school"
    },
    {
        "FieldID": "favorite subject",
        "FieldValue": "math"
    },
]
},
{
"_id": {
    "$oid": "511ff0a8521e66d41b0d35d7"
},
"FormID": {
    "$uuid": "413ba627-94bf-0ca7-49b3-9ca2a1a3e9b5"
},
"ResultID": {
    "$uuid": "45f455ae-8486-aaa9-b97a-e480bfdf3db5"
},
"FieldValues": [
    {
        "FieldID": "first name",
        "FieldValue": "sarah"
    },
    {
        "FieldID": "last name",
        "FieldValue": "smith"
    },
    {
        "FieldID": "school",
        "FieldValue": "high school"
    },
    {
        "FieldID": "favorite subject",
        "FieldValue": "english"
    },
]
},

假设我想投影结果Id,名,姓

在SQL中——我将在自己的表中定义FieldValues,我将对字段值进行子查询,其中ResultId =(父母的结果id)和FieldID ="名字",然后对"姓氏"等进行另一个子查询,以使结果变平。

我一直在试图弄清楚如何用mongo做到这一点。我能够找到$slice操作符,但这只能让您获得一组连续的数组元素。

我不想获得整个文档的原因是,在某些情况下,我的客户已经定义了400多个要跟踪的字段。即使在200行上反序列化所有这些数据也可能意味着通过网络传递100MB的数据并进行反序列化(慢)。

如有任何意见/建议,我将不胜感激

您可以构造一个适当的聚合框架语法来返回您想要的结果。它可能不够快,但它将返回您想要的确切格式,而无需拉下整个文档。为了使它更快,我假设您将避免在整个集合上运行它,方法是将管道的第一阶段设置为仅选择文档的相关子集(并且应该对该标准进行索引)的某个{$match}

在字段first namelast name的两个示例文档上使用以下管道阶段,您只返回_id和那些字段。对于一组给定的字段id,您可以以编程方式生成此管道。

unwind = { "$unwind" : "$FieldValues" };
match = { "$match" : {
        "FieldValues.FieldID" : {
            "$in" : [
                "first name",
                "last name"
            ]
        }
    }
};
proj = { "$project" : {
        "first name" : {
            "$cond" : [
                {
                    "$eq" : [
                        "first name",
                        "$FieldValues.FieldID"
                    ]
                },
                "$FieldValues.FieldValue",
                "  skip"
            ]
        },
        "last name" : {
            "$cond" : [
                {
                    "$eq" : [
                        "last name",
                        "$FieldValues.FieldID"
                    ]
                },
                "$FieldValues.FieldValue",
                "  skip"
            ]
        }
    }
};
group = { "$group" : {
        "_id" : "$_id",
        "first name" : {
            "$max" : "$first name"
        },
        "last name" : {
            "$max" : "$last name"
        }
    }
};
db.project.aggregate(unwind, match, proj, group)
{
    "result" : [
        {
            "_id" : ObjectId("511ff0a8521e66d41b0d35d7"),
            "first name" : "sarah",
            "last name" : "smith"
        },
        {
            "_id" : ObjectId("511ff0a8521e66d41b0d35d6"),
            "first name" : "John",
            "last name" : "smith"
        }
    ],
    "ok" : 1
}

相关内容

  • 没有找到相关文章