Mongodb 通过投影从嵌套文档中删除除一个字段以外的所有字段

Mongodb 通过投影从嵌套文档中删除除一个字段以外的所有字段,mongodb,mongodb-query,projection,aggregation-framework,Mongodb,Mongodb Query,Projection,Aggregation Framework,这是我的示例文档: { a: 42, map: { x: { ... }, y: { ... }, z: { ... } } } 我正在寻找一种返回的方式: { a: 42, map: { y: { ... } } } 我只想指定地图中要保留的字段。像这样的事 db.myCollection.find({}, { "map.y":1 } ) 但是它还应该返回字段a,而不显式指定它 我知道我还可以删除不需要的地图条目:

这是我的示例文档:

{
  a: 42,
  map: {
    x: { ... },
    y: { ... },
    z: { ... }
  }
}
我正在寻找一种返回的方式:

{
  a: 42,
  map: {
    y: { ... }
  }
}
我只想指定地图中要保留的字段。像这样的事

db.myCollection.find({},
  {
    "map.y":1
  }
)
但是它还应该返回字段
a
,而不显式指定它

我知道我还可以删除不需要的地图条目:

db.myCollection.find({},
  {
    "map.x":0,
    "map.z":0
  }
)
但是这样,在运行查询之前,我需要知道哪些映射键可用

有什么好办法处理这个问题吗?也许使用聚合框架


谢谢
:)

这就是MongoDB以及许多其他数据库系统中投影或字段选择的基本工作原理。这里的概念基本上是“全部或无”,即如果不指定要返回的所有字段,则不会返回这些字段,当然默认情况是在没有明确说明所需内容的情况下返回所有内容

因此,当前数据返回
a
map.y
的正确形式是:

db.myCollection.find({},{“a”:1,“map.y”:1})
当然,你也可以告诉它你不想要什么:

db.myCollection.find({},{“map.x”:0,“map.z”:0})
但是您不能“混合”包含和排除,唯一的例外是
\u id
字段,在该字段中,您不希望在结果中使用该字段,可能认为是“covered index”查询,但通常需要主键:

db.myCollection.find({},{u id:0,“a”:1,“map.y”:1})
至于聚合框架,它是一样的,对于和这样的运营商来说尤其残酷。在这两种情况下,您都需要准确地指定要返回的内容($project也遵循一般的投影规则),否则这些字段不会出现在结果中

事实上,我的员工犯的一个常见错误是,使用其中一个阶段“删除”字段,然后试图引用后来删除的字段。它是一个“管道”,就像Unix管道
|
一样,唯一流向下一阶段的内容是您指定的内容:

唯一一种“真正”的情况是,您可以在不指定其他字段的情况下排除除匹配字段以外的所有字段,方法是更改结构以将“map”实现为数组,然后使用pipeline阶段(可从MongoDB 2.6及更高版本获得)。尽管有点做作:

db.test.insert({
“a”:42,
“地图”:[
{“类型”:“x”,“内容”:{},
{“类型”:“y”,“内容”:{},
{“类型”:“z”,“内容”:{}
]
})
以及对如下结构的数据的聚合操作:

db.test.aggregate([
{“$redact”:{
“$cond”:[
{“$eq”:[
{“$ifNull”:[“$type”,“y”]},
“y”
]},
“$$下降”,
“$$PRUNE”
]
}}
])
因此,我们只要求将元素的“type”与“y”匹配,但这里通常需要小心,因为$redact是递归处理的,这就是为什么操作符在测试字段不存在的级别人为创建匹配


但一般来说,投影要么全是,要么什么都不是。指定要返回的字段,否则这些字段将不在那里。

太糟糕了,因为数组无法映射到我的Java类。但我当然可以解决这个问题
..
现在我有了第二个小问题:当使用数组方法处理
类型和
内容时,是否可以使用
$elemMatch
运算符的反面进行投影?即(伪代码)
map:{$elemMatch:{type:NOT“y”}}:0
,因此它将从数组中删除所有内容,其中
type!=“y”
@BenjaminM正如我所解释的那样,没有其他方法可以让另一个字段(如“a”)出现,而不明确表示希望返回该字段$编校是一种特殊情况,它从文档中“删除”元素,在这种情况下,“类型”字段不匹配。所以,没有其他方法就意味着没有其他方法。谢谢你,为这伟大的解释
地图吗
,这样我就可以轻松地使用标准投影了。