投影一个并不总是存在的字段

24

有没有一种方法可以投影可能存在或不存在的字段?例如,将其定义为null或未定义?

例如,我有一个查询:

$project: {
  date: 1,
  name: "$person.name",
  age: "$person.age"
}              

并非所有文档都保证有$person.age,但我希望没有年龄信息的文档返回{ date: Today, name: "Bill", age: null }或类似内容,而不是返回{ date: Today, name: "Bill" }

是否有比事后遍历数据并创建不存在的字段更好的方法?


2
拥有一个空值字段和根本没有该字段之间有什么区别? - Explosion Pills
我正在使用的一些模块,如果第一个文档没有特定字段而后面的文档中出现了该字段,则导出到Excel文件或在网格中打印时会留空该列。 - Peter Sampson
3个回答

47

使用$ifNull

  $project: {
     date: 1,
     name: "$person.name",
     age: { $ifNull: [ "$person.age", "null" ] }
  }  

你可以在这里了解更多信息。


1
看起来 $ifNull 只能用于聚合操作,而不能用于查找操作。 - Ed Spencer

3
这就是$ifNull表达式的用处所在。从文档中可知,$ifNull

计算一个表达式,并返回如果该表达式计算结果不为空,则该结果的值。如果该表达式计算结果为空,包括undefined值或缺少字段时,则返回替换表达式的值。

对于你的情况,以下将使用$ifNull表达式来返回非空的$person.age字段值,或者如果年龄字段为空或不存在,则返回字符串“未指定”:

 $project: {
     date: 1,
     name: "$person.name",         
     age: { $ifNull: [ "$person.age", "Unspecified" ] }
 }    

3

Mongo 5.3 开始,新的 $fill 聚合操作符是一个很好的使用案例:

// { name: "Bill", age: 23 }
// { name: "Peter" }
db.collection.aggregate(
  { $fill: { output: { age: { value: "Unspecified" } } } }
)
// { name: "Bill",  age: 23 }
// { name: "Peter", age: "Unspecified" }

缺失值或设置为null的值将使用给定常量Unspecified进行填充。

关于您的具体情况,您可以选择:

// { person: { name: "Bill", age: 23 } }
// { person: { name: "Peter" } }
db.collection.aggregate([
  { $project: { name: "$person.name" , age: "$person.age" } },
  { $fill: { output: { "age": { value: "Unspecified" } } } }
])
// { name: "Bill",  age: 23 }
// { name: "Peter", age: "Unspecified" }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接