关于php查询mongodb限制返回字段的问题
最近想做一个前端控制接口字段返回的一个基础方法,通过mongodb 的find($query,$field)查询来规定查询的字段,但是遇到这么一个问题:
工作代码中有两个封装方法 :
/**
* 查询一条记录
* @param string 集合名
* @param array 查询条件
* @param array 需要返回的字段
* @return array 查询的结果
*/
public function find_one($coll_name, $condition = array(), $ret_fields = array('_id' => 0)) {
return $this->docsdb->find_one($coll_name, $condition, $ret_fields);
}
/**
* 查询
* @param string 集合名
* @param array 查询的条件array<br/>如<i>array(col_a=>111)</i>
* @param array 集合过滤器array<br/>完整的样子想这个:<i>array(sort=>array(col_a=>1,col_b=>-1), skip=>100, limit=>10, timeout=>5000, immortal=>true)</i>,这表示:
* <ol>
* <li>wrapped 以wrapped为封装为数组的键,默认按数组先后顺序</li>
* <li>_id,默认不返回数据带有MongoID字段,如果指定了返回列的话也是一样的效果</li>
* <li>sort 以col_a为ASC,col_b为DESC排序,可以多列组合</li>
* <li>skip 表示从101条记录开始取数据,即跳过了前100条</li>
* <li>limit 本次选取的条数</li>
* <li>timeout 表示等待响应的时间(暂不使用)</li>
* <li>immortal 表示是否维持链接永久有效,默认true,此时timeout失效(暂不使用)</li>
* </ol>
* @param array 需要返回的字段(通常只返回必要的字段可以加快响应速度)
* @return mixed 查询的结果
*/
public function find($coll_name, $condition = array(), $result_filter = array('wrapped' => '', 'with_objectId' => 0, 'timeout' => 5000, 'immortal' => true), $ret_fields = array()) {
return $this->docsdb->find($coll_name, $condition, $result_filter, $ret_fields);
} **
'with_objectId' => 0 已在传入参数时设置为1
**
根据以上描述,$ret_fields就是mongodb find($query,$field)中的那个field,但是通过测试,我发现了这么一个问题,如果我想要去显示id,传入参数数组
$ret_fields = array(
'_id' => 1,
'account'=> 1,
'card' => 1
),
并调用find方法,根据理论来说,这个时候'_id'这个字段也是显示的,并且我通过这个条件直接查询mongodb,也是显示的,但是打印出来的数据却是不带id的,数据如下:
{
"account": "qwe",
"card": ""
}
***补充个测试结果,如果find方法不传入$ret_fields变量过去,即不限制返回字段的话,是存在'_id'的
通过修改条件,发现这个'_id' => 1 这个条件写不写都没用,于是我用相同的
$ret_fields去调用了find_one方法,这个时候竟然是返回'_id'字段的,数据如下
{
"_id": {
"$id": "58f472672430e11817000152"
},
"account": "qwe",
"card": ""
}
这个问题先记录在这吧,以后解决了再记录一下解决方法,如果有大神可以解释下这个原因,请不吝赐教,谢谢!
后续:通过查找底层的代码发现了如下封装:
/**
* 查询MongoDB
* @param string 集合名
* @param array 查询的条件array<br/>如<i>array(col_a=>111)</i>
* @param array 集合过滤器array<br/>完整的样子想这个:<i>array(sort=>array(col_a=>1,col_b=>-1), skip=>100, limit=>10, timeout=>5000, immortal=>true)</i>,这表示:
* <ol>
* <li>wrapped 以wrapped为封装为数组的键,默认按数组先后顺序</li>
* <li>_id,默认不返回数据带有MongoID字段,如果指定了返回列的话也是一样的效果</li>
* <li>sort 以col_a为ASC,col_b为DESC排序,可以多列组合</li>
* <li>skip 表示从101条记录开始取数据,即跳过了前100条</li>
* <li>limit 本次选取的条数</li>
* <li>timeout 表示等待响应的时间(暂不使用)</li>
* <li>immortal 表示是否维持链接永久有效,默认true,此时timeout失效(暂不使用)</li>
* </ol>
* @param array 需要返回的字段(通常只返回必要的字段可以加快响应速度)
* @return mixed 查询的结果
*/
public function find($coll_name, $condition = array(), $result_filter = array('wrapped' => '', 'with_objectId' => 0, 'timeout' => 5000, 'immortal' => true), $ret_fields = array()) {
$db_name = $this->db_name;
$cursor = $this->mongo->$db_name->$coll_name->find($condition, $ret_fields);
if (!empty($result_filter['skip'])) {
$cursor->skip($result_filter['skip']);
}
if (!empty($result_filter['limit'])) {
$cursor->limit($result_filter['limit']);
}
if (!empty($result_filter['sort'])) {
$cursor->sort($result_filter['sort']);
}
if (!empty($result_filter['wrapped'])) {
$wrapped = $result_filter['wrapped'];
} else {
$wrapped = '';
}
if (isset($result_filter['with_objectId']) && $result_filter['with_objectId'] == 1) {
//如果指定了返回的列此项目就失效
$with_objectId = count($ret_fields) < 1;
} else {
$with_objectId = 0;
}
if(!$with_objectId){
if (isset($ret_fields['with_objectId']) && $ret_fields['with_objectId'] == 1) { $with_objectId = 1;
} else {
$with_objectId = 0;
}
} $result = array();
$this->cursor = $cursor;
try {
if ($wrapped == '_id') {
while ($ret = $cursor->getNext()) {
$result[$ret['_id']->{'$id'}] = $ret;
}
} else if (strlen($wrapped)) {
while ($ret = $cursor->getNext()) {
$result[$ret[$wrapped]] = $ret;
}
} else {
while ($ret = $cursor->getNext()) {
$result[] = $ret;
}
}
if (!$with_objectId) {
foreach ($result as $key => $v) {
unset($result[$key]['_id']);
}
}
} catch (Exception $ex) {
$this->errors = $ex->getMessage();
}
return $result;
} 重点在于:
if(!$with_objectId){
if (isset($ret_fields['with_objectId']) && $ret_fields['with_objectId'] == 1) {
$with_objectId = 1;
} else {
$with_objectId = 0;
}
}
限定字段传入的参数名与mongodb不太一样,不能传_id,应该传with_objectId,这样就达到了需要的效果
ps:二次开发就是坑。
关于php查询mongodb限制返回字段的问题的更多相关文章
- MongoDB查询操作限制返回字段的方法
这篇文章主要介绍了MongoDB查询操作限制返回字段的方法,需要的朋友可以参考下 映射(projection )声明用来限制所有查询匹配文档的返回字段.projection以文档的形式列举结果集中 ...
- PDO 查询mysql返回字段整型变为String型解决方法
PDO 查询mysql返回字段整型变为String型解决方法 使用PDO查询mysql数据库时,执行prepare,execute后,返回的字段数据全都变为字符型. 例如id在数据库中是Int的,查询 ...
- PDO 查询mysql返回字段int变为String型解决方法
PDO 查询mysql返回字段int变为String型解决方法使用PDO查询mysql数据库时,执行prepare,execute后,返回的字段数据全都变为字符型. 例如id在数据库中是Int的,查询 ...
- 03 - Mongodb数据查询 | Mongodb
1.基本查询 ①方法find():查询 db.集合名称.find({条件文档}) ②方法findOne():查询,只返回第一个 db.集合名称.findOne({条件文档}) ③方法pretty(): ...
- hibernate框架之-查询结果集返回类型
Hibernate支持HQL和SQL的查询,返回结果支持POJO类型或字段/数组的形式. 开发中用Hibernate进行数据库查询,用的是SQL.原来需要查询一个表的几乎所有字段,所以我使用了addE ...
- Java 通过JDBC查询数据库表结构(字段名称,类型,长度等)
Java 通过JDBC查询数据库表结构(字段名称,类型,长度等) 发布者:唛唛家的豆子 时间:2012-11-20 17:54:02 Java 通过JDBC查询数据库表结构(字段名称,类型,长 ...
- 方法:查询MongoDB数据库中最新一条数据(JAVA)
使用JAVA语言查询MongoDB中某个数据库某个集合的最新一条数据: MongoCollection<Document> cpu = MongoClient.getDatabase(&q ...
- MongoDB数据查询 --MongoDB
1.插入测试数据 use flower db.goods.insert({'goods_name':'Hyacinth',price:10,num:800}) db.goods.insert({goo ...
- tp5.0 模型查询数据的返回类型,分页
一开始用painate()这个函数的时候,发现有的查询方式不能使用这个函数,由此了解到了模型查询和普通查询返回类型的不同 1.原生查询方法 Db::query("select * from ...
随机推荐
- windows环境安装MySQL
转:https://www.cnblogs.com/ayyl/p/5978418.html windows环境安装MySQL mySQL下载链接:MySQL Installer 5.7 :http:/ ...
- 剑指Offer 1. 二维数组中的查找 (数组)
题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...
- JS的小判断
// 0 if(undefined) { console.log('1'); } else { console.log('0'); } // 0 if(null) { console.log('1') ...
- Beta周王者荣耀交流协会第四次Scrum会议
1.立会照片 成员王超,高远博,冉华,王磊,王玉玲,任思佳,袁玥全部到齐. master:任思佳 2.时间跨度: 2017年11月13日 11:40 — 12:10 ,总计30分钟. 3.地点: 一食 ...
- erlang-gb_tree,gb_set
gb_tree, gb_set, 均为一个二叉树.具体怎么实现,这边不在累赘,官方有手册, how to use ? 才是我们的重点 1. 初始化 1> gb_trees:empty().{0, ...
- SQL-记录查询篇-009
在学习记录查询之前,学习一些关键字的使用: 1.逻辑运算符:and . or . not .is null select * from table_name where id>2 and ...
- UEFI+GPT双硬盘安装Win10+Ubuntu16.04双系统
转载请注明出处:http://www.cnblogs.com/willnote/p/6725594.html 安装环境 SSD+HDD双盘,Win10安装在SSD里,HDD分出来60G安装Ubuntu ...
- python base64.b64decode 等号可以随便加
由于 = 用在URL,cookie里会造成歧义,所以base64编码的时候,会把 = 自动去掉. 解码的时候,如果传入的二进制编码长度小于4的倍数,那么需要在后面补=,知道满足长度等于4的倍数,然后 ...
- asp.net core 基于角色的认证登陆
一.登陆页面的Controller [Authorize(Roles = "Admin,SuperAdmin")] public class ManageController : ...
- 廖雪峰Java6 IO编程-3Reader和Writer-2Writer
1.java.io.Writer和java.io.OutputStream的区别 OutputStream Writer 字节流,以byte为单位 字符流,以char为单位 写入字节(0-255):v ...