使用关系型数据库时,用户在select命令后添加字段名称控制返回字段。mongodb中也支持对查询返回字段的控制。默认返回文档的所有字段。为了限制返回数据量,提高网络传输速率。用户可以通过投射(projection)来指定返回字段或在返回结果中排除一些字段。
与本系列其他文章一样,首先构建测试集合。插入测试集合的文档,包含字符串类型的字段item和status, 嵌套文档类型字段size,文档数组类型字段instock.
//删掉已有集合
//db.inventory.drop()
//创建新的集合
db.inventory.insertMany( [
{ item: "journal", status: "A", size: { h: 14, w: 21, uom: "cm" }, instock: [ { warehouse: "A", qty: 5 } ] },
{ item: "notebook", status: "A", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "C", qty: 5 } ] },
{ item: "paper", status: "D", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "A", qty: 60 } ] },
{ item: "planner", status: "D", size: { h: 22.85, w: 30, uom: "cm" }, instock: [ { warehouse: "A", qty: 40 } ] },
{ item: "postcard", status: "A", size: { h: 10, w: 15.25, uom: "cm" }, instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);
当用户并未向mongodb查询语句指定任何投射规则时,默认返回所有字段。
下面的语句返回字段status是A的所有文档字段
db.inventory.find({status: 'A'})
通过添加投射规则,用户可以显示的指定字段的返回规则。在投射规则中,当字段名称后面指定为1时,该字段会被返回。当向字段指定为0时,该字段不会返回。_id字段,默认返回。
投射规则的语法如下
db.collection.find(
{ //定义查询条件
<field_name>: <value>,
...
},
{ //定义投射规则,设定字段是否返回
<field_name>: <0 or 1>,
...
}
)
下面语句中,返回item、status和_id字段
db.inventory.find({status: 'A'},{item: 1, status: 1})
_id字段默认是显示的,需要隐藏字段时,需要显示的在投射规则中添加_id:0
如只返回item和status字段
db.inventory.find({status: 'A'},{item: 1, status: 1, _id: 0})
在此查询语句中,定义了三个投射规则,item, status两个字段显示,_id字段隐藏。Mongodb在使用中规定,除了_id字段外,定义投射规则时,不能同时定义字段显示和隐藏。如用户只能定义item和status字段全部显示的{item: 1, status: 1}。不能定义item显示,status字段隐藏的规则{item: 1, status: 0}。而用户只能控制_id字段的隐藏,如{item: 1, status: 1, _id: 0}
如前面描述,为字段名称指定0值时,隐藏该字段。该字段在查询结果中不会返回。
如查询中不返回status和instock字段
db.inventory.find({status: 'A'},{status: 0, instock: 0})
与查询过滤文档一直,用户可以使用点操作符,构建嵌套字段路径,指定嵌套文档中字段的显示和隐藏。如下面的语句中,显示size文档中的uom字段
db.inventory.find({status: 'A'}, {item: 1, status: 1, "size.uom": 1})
同样,不使用点号,写成内嵌文档的方式,也是支持的。
db.inventory.find({status: 'A'}, {item: 1, status: 1, size: {uom: 1}})
而隐藏某些字段,只要将投射中的1改成0集合。
db.inventory.find({status: 'A'}, {size: {uom: 0}})
与嵌套文档操作类似,使用点操作符也可以控制文档数组中字段的显示和隐藏。
如下面的语句中,返回字段item, status, 和数组instock中文档的字段qty
db.inventory.find({status: 'A'}, {item: 1, status: 1, size: {uom: 1}, "instock.qty": 1})
除了控制文档字段显示以外, 使用投影,借助投影操作符,还可以控制数组元素的返回。详见后续文档。