只是想不出来。这是来自MongoDB作业的文档格式,它源自我无法控制的布局的XML文件:
{
"reference" : [ "93417" ],
"Title" : [ "RN - Pediatric Director of Nursing" ],
"Description" : [ "...a paragraph or two..." ],
"Classifications" : [
{
"Classification" : [
{
"_" : "Nurse / Midwife",
"name" : [ "Category" ]
},
{
"_" : "FL - Jacksonville",
"name" : [ "Location" ],
},
{
"_" : "Permanent / Full Time",
"name" : [ "Work Type" ],
},
{
"_" : "Some Health Care Org",
"name" : [ "Company Name" ],
}
]
}
],
"Apply" : [
{
"EmailTo" : [ "jess@recruiting.co" ]
}
]
}
目的是从数据库中提取作业列表,以包含“位置”,该位置被隐藏在“Classifications.Classification ._”的第二个文档中。
我尝试了$ project,$ unwind,$ match,$ filter,$ group的各种'聚合'排列......但我似乎没有得到任何结果。尝试只检索公司名称,我希望这可以工作:
db.collection(JOBS_COLLECTION).aggregate([
{ "$project" : { "meta": "$Classifications.Classification" } },
{ "$project" : { "meta": 1, _id: 0 } },
{ "$unwind" : "$meta" },
{ "$match": { "meta.name" : "Company Name" } },
{ "$project" : { "Company" : "$meta._" } },
])
但是这会为每条记录提供所有内容,因此:
[{
"Company":[
"Nurse / Midwife",
"TX - San Antonio",
"Permanent / Full Time",
"Some Health Care Org"
]
}, { etc etc }]
我错过了什么或滥用了什么?
答案 0 :(得分:0)
理想情况下,使用MongoDB 3.4,您只需$project
,并使用$map
,$filter
和$reduce
的数组运算符。后者为" compact"数组和前者要提取相关的元素和细节。同样$arrayElemAt
仅使用"元素"来自数组:
db.collection(JOBS_COLLECTION).aggregate([
{ "$match": { "Classifications.Classification.name": "Location" } },
{ "$project": {
"_id": 0,
"output": {
"$arrayElemAt": [
{ "$map": {
"input": {
"$filter": {
"input": {
"$reduce": {
"input": "$Classifications.Classification",
"initialValue": [],
"in": {
"$concatArrays": [ "$$value", "$$this" ]
}
}
},
"as": "c",
"cond": { "$eq": [ "$$c.name", ["Location"] ] }
}
},
"as": "c",
"in": "$$c._"
}},
0
]
}
}}
])
甚至可以跳过$reduce
只是将$concatArrays
应用于"合并"并简单地抓住第一个"数组索引(因为只有一个)使用$arrayElemAt
:
db.collection(JOBS_COLLECTION).aggregate([
{ "$match": { "Classifications.Classification.name": "Location" } },
{ "$project": {
"_id": 0,
"output": {
"$arrayElemAt": [
{ "$map": {
"input": {
"$filter": {
"input": { "$arrayElemAt": [ "$Classifications.Classification", 0 ] },
"as": "c",
"cond": { "$eq": [ "$$c.name", ["Location"] ] }
}
},
"as": "c",
"in": "$$c._"
}},
0
]
}
}}
])
这使得操作与MongoDB 3.2兼容,你应该"应该"至少跑步。
这反过来允许您根据" first"的初始输入变量,使用$indexOfArray
考虑MongoDB 3.4的替代语法。数组索引使用$let
来缩短语法:
db.collection(JOBS_COLLECTION).aggregate([
{ "$match": { "Classifications.Classification.name": "Location" } },
{ "$project": {
"_id": 0,
"output": {
"$let": {
"vars": {
"meta": {
"$arrayElemAt": [
"$Classifications.Classification",
0
]
}
},
"in": {
"$arrayElemAt": [
"$$meta._",
{ "$indexOfArray": [
"$$meta.name", [ "Location" ]
]}
]
}
}
}
}}
])
如果确实你认为那是"更短"那就是。
在另一种意义上,就像上面有一个"数组内部和数组",所以为了处理它,你$unwind
两次,实际上$concatArrays
$reduce
内部的9在理想情况下正在反击:
db.collection(JOBS_COLLECTION).aggregate([
{ "$match": { "Classifications.Classification.name": "Location" } },
{ "$unwind": "$Classifications" },
{ "$unwind": "$Classifications.Classification" },
{ "$match": { "Classifications.Classification.name": "Location" } },
{ "$project": { "_id": 0, "output": "$Classifications.Classification._" } }
])
所有陈述实际产生:
{
"output" : "FL - Jacksonville"
}
由原始意图选择的"_"
内部数组元素中"Location"
的匹配值。
请注意,所有语句的前面应该是相应的[$match
] {{3}}语句,如下所示:
{ "$match": { "Classifications.Classification.name": "Location" } },
由于没有它,您可能会不必要地处理文档,这实际上不包含与该条件匹配的数组元素。当然,由于文件的性质,情况可能并非如此,但确保"初始"通常是一种良好的做法。选择始终与您稍后打算提取的详细信息相匹配,并提取"。
所有这些都说,即使这是从XML直接导入的结果,也应该更改结构,因为它不能有效地呈现查询。 MongoDB文档不适用于XPATH在发出查询方面的工作方式。因此,任何事情" XML Like"不会是一个好的结构,如果" import"过程不能改变为更适应的格式,那么至少应该有一个"后期处理"以更实用的形式将其操作到一个单独的存储中。