关于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 ...
随机推荐
- find语法
语法 find path -option [ -print ] [ -exec -ok command ] {} \; 参数说明 : find 根据下列规则判断 path 和 expression,在 ...
- CreateThread给线程函数传递的参数
HANDLE WINAPI CreateThread ( __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, // 指向SECURITY_ATTR ...
- 将文件夹中的图像路径自动生成txt文件(便于opencv遍历处理图像)
代码: #include<iostream> #include<vector> #include<io.h> #include<fstream> usi ...
- 怎么解决mysql 执行SQL过长问题------------?
Could not execute JDBC batch update mysql中,in语句中参数个数是不限制的.不过对整段sql语句的长度有了限制(max_allowed_packet). 默认 ...
- node 创建server 及加载静态页面
1.Demo.js 创建Server let http = require('http'); let url = require("url"); let util = re ...
- Java并发--Java线程面试题 Top 50
原文链接:http://www.importnew.com/12773.html 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Ja ...
- SQLI DUMB SERIES-8
(1)在id后加单引号.无回显,加双引号跟正常输入是一样的回显,既然不会回显出错信息,只能进行盲注. (2)盲注的方法同less5
- [ Codeforces Round #549 (Div. 2)][D. The Beatles][exgcd]
https://codeforces.com/contest/1143/problem/D D. The Beatles time limit per test 1 second memory lim ...
- 421. Maximum XOR of Two Numbers in an Array
这题要求On时间复杂度完成, 第一次做事没什么思路的, 答案网上有不贴了, 总结下这类题的思路. 不局限于这个题, 凡是对于这种给一个 数组, 求出 xxx 最大值的办法, 可能上来默认就是dp, ...
- linux(ubuntu)共享文件夹
Linux系统的文件或目录的共享功能是非常强大,而且是非常灵活的,其对权限的控制可以做到非常的细致,当然如果你是通过命令行方式进行设置的 话,那么对于刚接触linux系统的用户来说将是一件十分头痛的事 ...