我正在使用动态表单构建器将值存储到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"
},
]
},
假设我想投影结果标识,名字,姓氏
在SQL中 - 我会在自己的表中定义FieldValues,我会对Field值进行子查询,其中ResultId =(parent的结果id)和FieldID =“first name”,然后是另一个子查询“姓氏”等等,以平衡结果。
我一直试图弄清楚如何用mongo做到这一点。我能够找到$ slice运算符,但这只能让你获得一组连续的数组元素。
我不想获得整个文档的原因是,在某些情况下,我的客户已经定义了400多个要跟踪的字段。对所有这些甚至200行进行反序列化可能意味着通过网络传递100MB数据并进行反序列化(慢速)。
任何意见/建议都将不胜感激
答案 0 :(得分:2)
您可以构造适当的聚合框架语法,以准确返回所需内容。它可能不够快,但它会返回您想要的确切格式,而不会将完整的文档拉下来。为了加快速度,我假设您可以避免在整个集合中运行它,方法是让管道的第一阶段为{$match}
,只选择相关的文档子集(并且该标准应该被编入索引)。
对于字段first name
和last 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
}