Mongodb 控制查询返回字段

使用关系型数据库时,用户在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'})

返回指定字段和_id字段

通过添加投射规则,用户可以显示的指定字段的返回规则。在投射规则中,当字段名称后面指定为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字段默认是显示的,需要隐藏字段时,需要显示的在投射规则中添加_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})

除了控制文档字段显示以外, 使用投影,借助投影操作符,还可以控制数组元素的返回。详见后续文档。