最近想做一个前端控制接口字段返回的一个基础方法,通过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限制返回字段的问题的更多相关文章

  1. MongoDB查询操作限制返回字段的方法

    这篇文章主要介绍了MongoDB查询操作限制返回字段的方法,需要的朋友可以参考下   映射(projection )声明用来限制所有查询匹配文档的返回字段.projection以文档的形式列举结果集中 ...

  2. PDO 查询mysql返回字段整型变为String型解决方法

    PDO 查询mysql返回字段整型变为String型解决方法 使用PDO查询mysql数据库时,执行prepare,execute后,返回的字段数据全都变为字符型. 例如id在数据库中是Int的,查询 ...

  3. PDO 查询mysql返回字段int变为String型解决方法

    PDO 查询mysql返回字段int变为String型解决方法使用PDO查询mysql数据库时,执行prepare,execute后,返回的字段数据全都变为字符型. 例如id在数据库中是Int的,查询 ...

  4. 03 - Mongodb数据查询 | Mongodb

    1.基本查询 ①方法find():查询 db.集合名称.find({条件文档}) ②方法findOne():查询,只返回第一个 db.集合名称.findOne({条件文档}) ③方法pretty(): ...

  5. hibernate框架之-查询结果集返回类型

    Hibernate支持HQL和SQL的查询,返回结果支持POJO类型或字段/数组的形式. 开发中用Hibernate进行数据库查询,用的是SQL.原来需要查询一个表的几乎所有字段,所以我使用了addE ...

  6. Java 通过JDBC查询数据库表结构(字段名称,类型,长度等)

    Java 通过JDBC查询数据库表结构(字段名称,类型,长度等) 发布者:唛唛家的豆子   时间:2012-11-20 17:54:02   Java 通过JDBC查询数据库表结构(字段名称,类型,长 ...

  7. 方法:查询MongoDB数据库中最新一条数据(JAVA)

    使用JAVA语言查询MongoDB中某个数据库某个集合的最新一条数据: MongoCollection<Document> cpu = MongoClient.getDatabase(&q ...

  8. MongoDB数据查询 --MongoDB

    1.插入测试数据 use flower db.goods.insert({'goods_name':'Hyacinth',price:10,num:800}) db.goods.insert({goo ...

  9. tp5.0 模型查询数据的返回类型,分页

    一开始用painate()这个函数的时候,发现有的查询方式不能使用这个函数,由此了解到了模型查询和普通查询返回类型的不同 1.原生查询方法 Db::query("select * from ...

随机推荐

  1. 获取当前时间并格式化,CTime类

    CTime类,此类应该不是C++标准类库,属于windows封装的关于时间的类库,使用环境应该为 Win32程序,MFC程序,VC++程序 CTime tm = CTime::GetCurrentTi ...

  2. 记解决一次“HTTP Error 400. The request URL is invalid”的错误

    今天将图片服务切到使用了cdn的机器上面去,然后就部分图片报如下图错误“HTTP Error 400. The request URL is invalid” 看到这种错误信息,一般的开发者心中可能会 ...

  3. Python 测试多进程的时间

    import time from multiprocessing import Process def f1(): time.sleep(2) print("子进程1号") def ...

  4. 剑指Offer 6. 旋转数组的最小数字 (数组)

    题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋 ...

  5. L2-010. 排座位(并查集)*

    L2-010. 排座位 参考博客 #include<iostream> #include<math.h> using namespace std; ]; ][]; int fi ...

  6. 自动化测试-12.selenium的弹出框处理

    前言 不是所有的弹出框都叫alert,在使用alert方法前,先要识别出到底是不是alert.先认清楚alert长什么样子,下次碰到了,就可以用对应方法解决. alert\confirm\prompt ...

  7. 【oracle入门】数据库系统结构----三级模式

    概念模式:概念模式也称模式,是对数据库中全局数据路基结构的描述,是全体用户公共的数据视图.这种描述是抽象描述,不涉及具体硬件环境与平台,也与具有软件环境无关. 外模式:外模式也称子模式或者用户模式,他 ...

  8. 小程序仿QQ侧滑例子

    缩放:wxml <!--page/one/index.wxml--> <view class="page"> <view class="pa ...

  9. 【转载】 Pytorch 细节记录

    原文地址: https://www.cnblogs.com/king-lps/p/8570021.html ---------------------------------------------- ...

  10. 移动端IOS 固定下方的输入框,点击输入框位置会变的修复

    if(data=="ios"){ var _this = $(".publish"); //无键盘时输入框到浏览器窗口顶部距离 var noInputViewH ...