[已解决]mongoose如何多层查询?
发布于 8 年前 作者 TinyMattew 5881 次浏览 来自 问答

我有四张表 一张表是Category存放网站的目录分类以及子目录 一张表是Intro是介绍模块,存放属于介绍模块的分类及数据 一张表是News是新闻模块,存放属于新闻模块的分类及数据 一张表是Product是产品模块,存放属于产品模块的分类及数据

var CategorySchema = new mongoose.Schema({
    key:String,
    catname:String,
    subcategories:[{
        key:String,
        catname:String,
        module:String
    }]
});

var cateList=[{
    key:"about",
    catname:"走进企业",
    subcategories:[{
        key:"about",
        catname:"企业概况",
        module:"intro"
    },{
        key:"ideal",
        catname:"企业理想",
        module:"intro"
    },{
        key:"honour",
        catname:"企业荣誉",
        module:"intro"
    }]
},{
    key:"news",
    catname:"动态资讯",
    subcategories:[{
        key:"news",
        catname:"企业动态",
        module:"news"
    },{
        key:"industry-info",
        catname:"行业资讯",
        module:"news"
    },{
        key:"new-arrival",
        catname:"新品上市",
        module:"product"
    }]
}];

假设已经通过cateList把数据填充进去了 请问如何筛选出Category中分别属于intro模块、news模块、product的分类? 如果单纯的find像这样会把整条数据中一个符合的就会返回

 Category.find({'subcategories.module':'news'}).exec(function(err,docs){
            if(err) return callback(err);
            if(docs){
                callback(null,docs);
            }
        });

我希望返回的结果就只有模块为news的Subcategories

    {
        key:"news",
        catname:"企业动态",
        module:"news"
    },{
        key:"industry-info",
        catname:"行业资讯",
        module:"news"
    }

对mongoose操作还不熟悉,查阅了资料是要用到populate?还是aggregate? 可能描述上还不是很清楚,但是真心求大神帮助

19 回复

aggregate的$unwind应该可以满足你的需求

@pauky 谢谢你的建议,可是unwind不是只是吧数据拆开,但是具体的查询还是把不相关的如product等都取出来了。能再具体点吗?谢谢你

用$unwind将数据拆分,如果你想把里面那一层的数据拿到上一层,可再用$project将数据上移。具体可看看mongodb文档,哈哈。

@pauky 我通过

Category.aggregate().unwind('subcategories').match({'subcategories.module':'intro'})\

获取到了

[ { _id: 575cba20ec865b320aa3b98c,
    subcategories: { key: 'new-arrival', catname: '新品上市', module: 'intro' } },
  { _id: 575cba20ec865b320aa3b988,
    subcategories: { key: 'about', catname: '企业概况', module: 'intro' } },
  { _id: 575cba20ec865b320aa3b988,
    subcategories: { key: 'ideal', catname: '企业理想', module: 'intro' } },
  { _id: 575cba20ec865b320aa3b988,
    subcategories: { key: 'honour', catname: '企业荣誉', module: 'intro' } } ]

但是页面打印出来的是[object Object],是我写的问题,还是需要转换?另外如何把获取到4个到1个subcategories里,谢谢啦

输出“[object Object]”是因为转换成字符串了,你是直接console.log输出结果集吗? 想合并的话,{$project: {subcategories: {$push: “$subcategories”}}}这样应该是可以的

@pauky 谢谢回答,console.log(docs)输出的话是[{…},{…}]是可以看到结果,但是渲染到页面就变成[object Object]了,之前使用find()的方法是可以直接渲染出json的结果的。{$project: {subcategories: {$push: “$subcategories”}}}似乎不起作用,刚才尝试了下,没有报错,但是没有返回任何结果

@pauky 我通过group实现了将下列结果分组到一起了

.group({ _id: "$subcategories" })

但是还是没有解决[object Object]的问题,需要docs转化为json,然道要用JSON.stringify吗?很奇怪

JSON.stringify之后再console.log

@pauky 但是这样处理的话,渲染到页面通过each循环都只能哪个一个个字符,而非对象了

在页面上JSON.parse

前端是可以从服务器上获取到json格式的数据的,应该是你前端获取或者服务端返回时没有指定数据类型造成的

@pauky 眼拙,发现group根本没用

[ { _id: 
     { key: 'honour',
       catname: '企业荣誉',
       module: 'intro',
       _id: 575cba20ec865b320aa3b989 } },
  { _id: 
     { key: 'ideal',
       catname: '企业理想',
       module: 'intro',
       _id: 575cba20ec865b320aa3b98a } },
  { _id: 
     { key: 'about',
       catname: '企业概况',
       module: 'intro',
       _id: 575cba20ec865b320aa3b98b } },
  { _id: 
     { key: 'new-arrival',
       catname: '新品上市',
       module: 'intro',
       _id: 575cba20ec865b320aa3b98d } } ]

只是变成这样而已

唉,通过aggregate处理的数据就不能像find那样直接使用吗

aggregate和find的结果都是json数据呀!有啥不一样?

db.test.aggregate([{$group: {_id: “$subcategories.module”, data: {$push: “$subcategories”}}}]) data.png

@pauky 谢谢,group_id如果都设为$subcategories.module就不会分成两个啦,这样OK的! 我的奇怪地方就是find出来都能直接渲染在页面,而聚合出来的就只有[object Object]然后还需要转换格式 比较不理解,怕是自己操作不当造成

@pauky 前端部分目前使用jade模版做数据测试,可能之后换成angular吧,目前jade是渲染不出来

@pauky 啊!谢谢啦,我知道问题所在了,因为我数据结构早已换了,jade模版要换一种方式获取数据,现在OK了!十分感谢!

@TinyMattew 不客气,解决了就好

回到顶部