我已经完成了this popular question。所描述的解决方案都没有真正解决我的问题。我也经历过其他职位,徒劳无功。
我想找到具有查询的特定投影字段(投影字段可以是数组的一部分),该查询由嵌套数组的不同深度处的对象组成。我的文档中的数组嵌套最多可达5个级别。我使用$match
,$and
来组合我的所有条件,使用$elemMatch
来嵌套数组。查询部分本身工作正常,它找到了正确的文档。然而问题是在投影所需的字段时(其中一些字段属于深层嵌套数组)
对我的情况不起作用的解决方案及原因:
$filter
:从3.2版开始提供。我使用的是3.0版。 $ filter不是一个选项。 $unwind
:我的嵌套数组(以下示例中的Array3和Array6)有8000个数组元素。根据{{1}}的定义,它将创建一个包含重复数据的单独文档流。这不是我们想要做的事情,因为文件很大并且重复,数千次似乎不是一个好主意。如果我遗漏了$unwind
的内容,请告诉我。 $unwind
和$elemMatch
:两者都只返回数组中的一个匹配对象。我希望数组中有多个符合特定条件的对象进行投影。 $ operator
:我尝试了in this answer所述的方法。不确定它是否是采用嵌套数组的正确方法。对于没有嵌套数组的简单示例,它(在某种程度上)起作用下面是一个示例文档,预期结果和一些接近解决问题的事情,但并不完全。
示例文档(我的集合中的实际文档。名称已更改,数组元素已减少。我不是这样做的。我正在使用的数据实际上是嵌套的。此外最内层的数组可以拉伸到有8000个元素):< / p>
$redact
查询:以下所有<和
投影:
预期结果:
{
"Name" : "fa191a58-3c8b-4533-9545-3379e996c0b7",
"Type" : "67448a7f-c514-4dc4-9836-4be6f54572a7",
"DataObj" : {
"Community" : [
{
"Name" : "5e6ac308-5e14-4c83-8111-55f87f3bab17",
"DataPoints" : {
"Person" : {
"ItemCount" : 777,
"NameCount" : NumberInt(999),
"LevelCount" : NumberInt(999)
},
"Houses" : [
{
"DoorNumber" : NumberInt(4),
"MatNumber" : 777,
"Person" : {
"ItemCount" : NumberInt(999),
"NameCount" : NumberInt(999),
"OneTwoDetails" : {
"WholeObj" : {
"OneTwo123" : {
"One1X" : 999.9,
"One2X" : 999.9,
"One3X" : 999.9
}
},
"Houses" : [
{
"DoorNumber" : NumberInt(999),
"MatNumber" : NumberInt(999),
"OneTwo123" : {
"One1X" : 999.9,
"One2X" : 999.9,
"One3X" : 999.9
},
"Rooms" : [
{
"LengthX" : NumberInt(999),
"LengthY" : NumberInt(999),
"OneTwo123" : {
"One1X" : 777,
"One2X" : 999.9,
"One3X" : 999.9
}
},
{
"LengthX" : NumberInt(999),
"LengthY" : NumberInt(999),
"OneTwo123" : {
"One1X" : 999.9,
"One2X" : 999.9,
"One3X" : 999.9
}
}
]
}
]
},
"ApplianceCount" : NumberInt(999),
"UtilityPowerCount" : NumberInt(999),
"UtilityPowerDetails" : [
{
"Name" : "d0f587f8-0a5a-4cd8-aa40-b8ca6e725f27",
"Range" : 999.9
},
{
"Name" : "76626240-2f58-44d0-8a53-0c161cd6ce58",
"Range" : 999.9
}
]
}
}
]
},
"DataSearching" : {
"SearchSequence" : NumberInt(999),
"SearchedDetails" : {
"TagX" : 999.9,
"TagY" : 999.9
},
"Houses" : [
{
"Sequence" : NumberInt(4),
"SearchedDetails" : {
"TagX" : 999.9,
"TagY" : 999.9
},
"Rooms" : [
{
"Sequence" : NumberInt(999),
"Clauses" : [
{
"Value" : 777,
"IsLimited" : true
},
{
"Value" : 999.9,
"IsLimited" : true
}
]
}
]
}
]
}
}
]
}
}
我使用以下方法取得了部分成功,但我不知道如何使这个工作适用于嵌套数组。
没有嵌套数组的文档:
{
"DataObj" : {
"Community" : [
{
"DataPoints" : {
"Person" : {
"ItemCount" : 777
},
"Houses" : [
{
"MatNumber" : 777,
"Person" : {
"OneTwoDetails" : {
"Houses" : [
{
"Rooms" : [
{
"OneTwo123" : {
"One1X" : 777
}
}
]
}
]
}
}
}
]
},
"DataSearching" : {
"Houses" : [
{
"Rooms" : [
{
"Clauses" : [
{
"Value" : 777
}
]
}
]
}
]
}
}
]
}
}
采取的方法(在另一个StackOverflow问题中找到):
{
"_id" : ObjectId("57154af04b42aa1fd05fe9fe"),
"Element1" : "5e6ac308-5e14-4c83-8111-55f87f3bab17",
"Element2" : NumberInt(1),
"Array1" : [
{
"Array1Elem1" : NumberInt(666),
"Array1Elem2" : 1999.0,
"Array1Elem3" : 999,
"Array1Elem4" : 999
},
{
"Array1Elem1" : NumberInt(999),
"Array1Elem2" : 999.9,
"Array1Elem3" : 999,
"Array1Elem4" : 999
},
{
"Array1Elem1" : NumberInt(999),
"Array1Elem2" : 999.9,
"Array1Elem3" : 999,
"Array1Elem4" : 999
},
{
"Array1Elem1" : NumberInt(999),
"Array1Elem2" : 999.9,
"Array1Elem3" : 999,
"Array1Elem4" : 999
},
{
"Array1Elem1" : NumberInt(444),
"Array1Elem2" : 2999,
"Array1Elem3" : 999,
"Array1Elem4" : 999
}
]
}
结果(几乎我需要的。不完全返回所询问的投影字段,但至少它只返回与条件匹配的数组元素。我可以使用它):
db.collectionName.aggregate(
{ "$match" : {
$and : [
{ Array1 : {
$elemMatch: {
"Array1Elem1": {$lt : 999},
"Array1Elem2" : {$gt : 1200}
}
}
},
{
// other conditions
}
]
}
},
{ "$project" : {
"Array1" : {
"$setDifference" : [
{ "$map" : {
"input" : "$Array1",
"as" : "element",
"in" : {
"$cond" : [
{ "$and" : [
{"$lt" : ["$$element.Array1Elem1", 999]},
{"$gt" : ["$$element.Array1Elem2", 1200]}
]
},
{"$cond" : [1, "$$element", 0]},
false
]
}
}},
[false]
]
}
}
})
如果我可以将行为扩展到嵌套数组,我可以使用它。如果有任何其他方法可以实现嵌套数组的投影,请讨论。