关于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 ...
随机推荐
- 通过pid杀死进程
bool ****::KillProcess(DWORD pid) { // When the all operation fail this function terminate the " ...
- 关于itext生成pdf的新的demo(包含简单的提取txt文件的内容 和xml内容转化为pdf)
一.用的iText版本为7.0.2版本,maven的配置如下: <dependencies> <!-- always needed --> <dependency> ...
- solr实现动态加载分词
版本是5.3.0 在core(自己创建的模块)的schema.xml里面增加类型: <fieldType name="text_lj" class="solr.Te ...
- python------Socket网略编程+动态导入模块
上节课程回顾: 静态变量:与类无关,不能访问类里的任何属性和方法. 类方法:只能访问类变量. 属性:把一个方法变成静态属性, 反射: __new__:先于__init__执行: __call__: c ...
- 推荐一些关于学习Html Css和Js的书吗?
前端易学易懂,随着移动互联网的日益兴起,it行业对于前端的需求也在不断的提高,那么从前端小白修炼成为前端大神的这个过程之中,一些必备的枕边书也是必不可少的. 第一本,入门<Head first ...
- vue企业项目搭建过程(vue-cli脚手架超详细教程 傻瓜-入门)
vue作为现在主流的前端框架,有必要学习一下. vue的官方文档还是不错的,开源中文,一个爽字形容. 如果不是实际开发需要vue-cli构建项目,那么可以在加一个爽. 然而要构建的时候发现官方文档还是 ...
- jenkins构建完成后,执行的命令行的东西也会自动结束的解决办法
问题: 把添加VPN的指令写在脚本里,然后用jenkins执行这个脚本,jenkins执行的结果是成功的,但是在机器上看,并没有执行成功. 问题分析: 其实在机器上执行过添加VPN的操作,只是在j ...
- 洛谷P1443马的遍历
传送 这是个广搜,思路和普通的迷宫题差不多,但我卡了3遍,为什么呢? 因为输出格式 题目要求左对齐,宽度为5输出,在此说一下如何控制宽度. 下面的m都为要求的宽度 int 类型: printf: %m ...
- nginx的启动,停止和重启
启动 启动代码格式:nginx安装目录地址 -c nginx配置文件地址 例如: [root@LinuxServer sbin]# /usr/local/nginx/sbin/nginx -c /us ...
- 高性能mysql 第五章 索引部分总结
高性能索引 1.索引基础:索引的作用类似'目录'帮助Query来快速定位数据行. 1.1索引类型: 1.1.1 b-tree索引 b-tree(balance tree)索引:使用平衡树(非平衡二叉树 ...