var PersonSchema = new Schema({ name: {type: String}, friends: [ { name: {type: String}, phone: {type: String}, } ] });
mongoose.model(‘Person’,PersonSchema);
实体数据如下: var person = { name: ‘zhangsan’, friends: [ { _id:ObjectID, name:‘lisi’, phone:‘123’ }, { _id:ObjectID, name:‘wangwu’, phone:‘456’ }, { _id:ObjectID, name:‘zhaoliu’, phone:‘789’ } ] }
我现在只要得到 friends中 name=='wangwu’的数据,仅此一条, 如何操作呢。
Person.findOne({_id: 已知}) .exec(function(error,success){ console.log(success); //这个success中是全部的friends });
有没有直接findOne到当前文档的嵌套部分的指定_id呢
==============研究了两天 终于搞定 推荐大家使用============= // 聚合框架效率高 var now=new Date(); Person.aggregate( {$match: {_id: ‘这个已知是个参数’}}, //首先去match这个人的ID,取得一条 {$project: {friends: 1,_id: 0,name:1}}, //为1表示要这个属性,为0表示不要 {$unwind: ‘$friends’}, //展开friends 子文档 数组 {$match: {‘friends._id’: ‘这个已知是个参数,比如是从friends列表中取的’}}, //取match {$group: { //组织要output的 friends:{$push: ‘$friends’}, _id: null, name: {$first: ‘$name’} } }, function(error,reply){ var buffer = reply[0].chapter[0]; // console.log(’======= ',buffer); //测试的时候可以放开,运行时必须去掉,因为会影响处理速度,当friends为100条时,只用了5ms就搞定了。 console.log(‘time :’+(new Date().getTime()-now.getTime())+‘ms’); } );
-----------------------------------处理同样的数据要25ms左右,是聚合框架查询的5倍---------------------- // 普通查询效率低 // Person.findOne({_id: ‘这个已知是个参数’}) // .select(‘friends’) // .exec(function(error,detail){ // if(error || !detail){ // return; // } var buffer = []; // for(var i= 0,len = detail.friends.length;i < len; i += 1){ // friends= detail.friends[i]; // if(这个已知是个参数,比如是从friends列表中取的 === friends._id){ // buffer = friends; // } // } console.log(buffer); // tools.log(‘time :’+(new Date().getTime()-now.getTime())+‘ms’); // });
这个是无法实现的好像
拿到数据以后自己排除一下吧…
没人知道吗?
http://mongoosejs.com/docs/subdocs.html 这个里面的Finding a sub-document不是么
@a272121742 我只要得到 如下的数据格式,带有Person的属性name 和 只有一条子文档的全部属性。 var person = { name: ‘zhangsan’, friends: [ { { _id:ObjectID, name:‘wangwu’, phone:‘456’ } ] }
就是我只想看到 zhangsan的第二个朋友的name和phone 如果用,person.friends 去循环,再与子文档的_id比较,也是可以得到的,但如果子文档有10000个朋友,我们就要循环10000次的match。 var f = person.friends; //这个可以能过ID取得 var buffer = []; for(var i=0,len=f.length;i < len; i += 1){ if( f[i]._id === 传入的参数){ buffer.push( f[i]); }
}
console.log(buffer); 这样是可以得到的。如果数据量大了,怎么办。一条微薄有10000个回复,我们总不能去mathc这10000条吧。
嗯,你的问题我也不懂,我只能说如果内嵌文档在不断更新变大的话,就不适合作为内嵌文档了
使用聚合框架终于搞定
@sogego mongoose暂时做不到应该,或者说我没用到。分析了下也觉得mongoose很难做到,除非有其他的工具
@a272121742 lz已经解决了 –
如果追求效率高,直接调用mongodb的原生js查询,配合index,何必还要框架呢。
怎么总有人挖坟。。
建议陈旧的帖子被顶了也上不来
哈哈 原来mongodb支持这么多种聚合 http://docs.mongodb.org/manual/core/aggregation-introduction/ 感觉自己有点孤陋寡闻啊·· aggregate中文文档: http://www.w3cschool.cc/mongodb/mongodb-aggregate.html
貌似很吊