Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 用mongoose查询嵌套文档_Javascript_Node.js_Mongodb_Mongoose_Aggregation Framework - Fatal编程技术网

Javascript 用mongoose查询嵌套文档

Javascript 用mongoose查询嵌套文档,javascript,node.js,mongodb,mongoose,aggregation-framework,Javascript,Node.js,Mongodb,Mongoose,Aggregation Framework,我知道这个问题已经被问了很多次了,但我对猫鼬和猫鼬也有点陌生,我想不出来 我的问题是: 我有一个像这样的 var rankingSchema = new Schema({ userId : { type : Schema.Types.ObjectId, ref:'User' }, pontos : {type: Number, default:0}, placarExato : {type: Number, default:0}, golVencedor : {t

我知道这个问题已经被问了很多次了,但我对猫鼬和猫鼬也有点陌生,我想不出来

我的问题是:

我有一个像这样的

var rankingSchema = new Schema({
    userId : { type : Schema.Types.ObjectId, ref:'User' },
    pontos : {type: Number, default:0},
    placarExato : {type: Number, default:0},
    golVencedor : {type: Number, default:0},
    golPerdedor : {type: Number, default:0},
    diferencaVencPerd : {type: Number, default:0},
    empateNaoExato : {type: Number, default:0},
    timeVencedor : {type: Number, default:0},
    resumo : [{
        partida : { type : Schema.Types.ObjectId, ref:'Partida' },
        palpite : [Number],
        quesito : String
    }]
});
{
    "_id" : ObjectId("539d0756f0ccd69ac5dd61fa"),
    "diferencaVencPerd" : 0,
    "empateNaoExato" : 0,
    "golPerdedor" : 0,
    "golVencedor" : 1,
    "placarExato" : 2,
    "pontos" : 78,
    "resumo" : [ 
        {
            "partida" : ObjectId("5387d991d69197902ae27586"),
            "_id" : ObjectId("539d07eb06b1e60000c19c18"),
            "palpite" : [ 
                2, 
                0
            ]
        }, 
        {
            "partida" : ObjectId("5387da7b27f54fb425502918"),
            "quesito" : "golsVencedor",
            "_id" : ObjectId("539d07eb06b1e60000c19c1a"),
            "palpite" : [ 
                3, 
                0
            ]
        }, 
        {
            "partida" : ObjectId("5387dc012752ff402a0a7882"),
            "quesito" : "timeVencedor",
            "_id" : ObjectId("539d07eb06b1e60000c19c1c"),
            "palpite" : [ 
                2, 
                1
            ]
        }, 
        {
            "partida" : ObjectId("5387dc112752ff402a0a7883"),
            "_id" : ObjectId("539d07eb06b1e60000c19c1e"),
            "palpite" : [ 
                1, 
                1
            ]
        }, 
        {
            "partida" : ObjectId("53880ea52752ff402a0a7886"),
            "quesito" : "placarExato",
            "_id" : ObjectId("539d07eb06b1e60000c19c20"),
            "palpite" : [ 
                1, 
                2
            ]
        }, 
        {
            "partida" : ObjectId("53880eae2752ff402a0a7887"),
            "quesito" : "placarExato",
            "_id" : ObjectId("539d0aa82fb219000054c84f"),
            "palpite" : [ 
                2, 
                1
            ]
        }
    ],
    "timeVencedor" : 1,
    "userId" : ObjectId("539b2f2930de100000d7356c")
}
将返回如下文档:

var rankingSchema = new Schema({
    userId : { type : Schema.Types.ObjectId, ref:'User' },
    pontos : {type: Number, default:0},
    placarExato : {type: Number, default:0},
    golVencedor : {type: Number, default:0},
    golPerdedor : {type: Number, default:0},
    diferencaVencPerd : {type: Number, default:0},
    empateNaoExato : {type: Number, default:0},
    timeVencedor : {type: Number, default:0},
    resumo : [{
        partida : { type : Schema.Types.ObjectId, ref:'Partida' },
        palpite : [Number],
        quesito : String
    }]
});
{
    "_id" : ObjectId("539d0756f0ccd69ac5dd61fa"),
    "diferencaVencPerd" : 0,
    "empateNaoExato" : 0,
    "golPerdedor" : 0,
    "golVencedor" : 1,
    "placarExato" : 2,
    "pontos" : 78,
    "resumo" : [ 
        {
            "partida" : ObjectId("5387d991d69197902ae27586"),
            "_id" : ObjectId("539d07eb06b1e60000c19c18"),
            "palpite" : [ 
                2, 
                0
            ]
        }, 
        {
            "partida" : ObjectId("5387da7b27f54fb425502918"),
            "quesito" : "golsVencedor",
            "_id" : ObjectId("539d07eb06b1e60000c19c1a"),
            "palpite" : [ 
                3, 
                0
            ]
        }, 
        {
            "partida" : ObjectId("5387dc012752ff402a0a7882"),
            "quesito" : "timeVencedor",
            "_id" : ObjectId("539d07eb06b1e60000c19c1c"),
            "palpite" : [ 
                2, 
                1
            ]
        }, 
        {
            "partida" : ObjectId("5387dc112752ff402a0a7883"),
            "_id" : ObjectId("539d07eb06b1e60000c19c1e"),
            "palpite" : [ 
                1, 
                1
            ]
        }, 
        {
            "partida" : ObjectId("53880ea52752ff402a0a7886"),
            "quesito" : "placarExato",
            "_id" : ObjectId("539d07eb06b1e60000c19c20"),
            "palpite" : [ 
                1, 
                2
            ]
        }, 
        {
            "partida" : ObjectId("53880eae2752ff402a0a7887"),
            "quesito" : "placarExato",
            "_id" : ObjectId("539d0aa82fb219000054c84f"),
            "palpite" : [ 
                2, 
                1
            ]
        }
    ],
    "timeVencedor" : 1,
    "userId" : ObjectId("539b2f2930de100000d7356c")
}
我的问题是,首先:如何按quesito筛选resumo嵌套文档?由于该数组将增加,是否可以对该结果进行分页。最后一个问题,这是处理这个案子的好方法吗


谢谢你们

我不确定您是否可以直接使用mongoose筛选子文档。但是,您可以使用
Model.find({'resumo.quesito':'THEVALUE'})获取父文档
(您还应该在其上添加索引)

当你有了父母,你可以通过比较问题来得到孩子


可以在此处找到附加文档:

如前所述,您的模式意味着您实际上拥有嵌入的数据,即使您正在存储外部引用。因此,不清楚您是同时进行嵌入和引用,还是只进行自身嵌入

这里最大的警告是匹配“文档”和实际过滤数组内容之间的区别。因为您似乎在谈论“分页”数组结果,所以这里的重点是这样做,但仍然提到警告

数组中的多个“筛选”匹配项需要聚合框架。通常,您可以“投影”一个数组元素的单个匹配项,但如果需要多个匹配项,则需要这样做:

Ranking.aggregate(
    [ 
        // This match finds "documents" that "contain" the match
        { "$match": { "resumo.quesito": "value" } },

        // Unwind de-normalizes arrays as documents
        { "$unwind": "$resumo" },

        // This match actually filters those document matches
        { "$match": { "resumo.quesito": "value" } },

        // Skip and limit for paging, which really only makes sense on single
        // document matches
        { "$skip": 0 },
        { "$limit": 2 },

        // Return as an array in the original document if you really want
        { "$group": {
            "_id": "$_id",
            "otherField": { "$first": "$otherField" },
            "resumo": { "$push": "$resumo" }
        }}
    ],
    function(err,results) {


    }
)
或MongoDB 2.6方式,通过使用运算符在内部进行“过滤”。但您仍然需要“分页”数组位置,但由于数组首先被“过滤”,因此处理可能会更少:

只有在处理单个文档并对数组进行“筛选”和“分页”时,and的内部用法才有意义。可以对多个文档执行此操作,但是非常复杂,因为无法仅对数组进行“切片”。这就引出了下一点

实际上,对于嵌入式阵列,对于不需要任何过滤的分页,您只需使用运算符即可,该运算符就是为此目的而设计的:

Ranking.find({},{ "resumo": { "$slice": [0,2] } },function(err,docs) {

});
您的替代方法是简单地引用外部集合中的文档,然后将参数传递给mongoose以过滤和“分页”结果。模式本身的变化只是:

    "resumo": [{ "type": "Schema.Types.ObjectId", "ref": "Partida" }]
外部引用集合现在保存对象细节,而不是直接嵌入到数组中。与筛选和分页一起使用的是:

 Ranking.find().populate({
     "path": "resumo",
     "match": { "questio": "value" },
     "options": { "skip": 0, "limit": 2 }
 }).exec(function(err,docs) {

     docs = docs.filter(function(doc) {
         return docs.comments.length;   
     });
 });
当然,可能存在的问题是,您无法再实际查询包含“嵌入”信息的文档,因为它现在位于另一个集合中。这将导致拉入所有文档,尽管可能是通过其他一些查询条件,但随后手动测试它们,以查看它们是否由发送用于检索这些项目的过滤查询“填充”

所以这确实取决于你在做什么,你的方法是什么。如果您经常打算在内部数组上“搜索”,那么嵌入通常更适合您。另外,如果您真的只对“分页”感兴趣,那么操作符可以很好地处理嵌入文档。但要注意,嵌入式阵列的增长太大了

在mongoose中使用引用模式有助于解决一些大小问题,并且有适当的方法来帮助“分页”结果并过滤它们。缺点是您不能再从父元素本身“内部”查询这些元素。因此,内部元素的父选择在这里不太合适。还请记住,虽然并非所有数据都已嵌入,但仍然存在对外部文档的
\u id
值的引用。因此,您仍然可以使用大型阵列,这可能并不理想


对于任何大的情况,考虑你可能自己在做这项工作,并且从“子”项目向后工作,然后与父(S)匹配。

这不是已经这样返回了吗?在这里,您似乎混合了嵌入设计和引用设计。虽然您确实提供了外部对象引用,但您似乎已经在嵌入式结构中定义了包含的字段。你实际上是如何保存数据的?我不知道这有什么用,我已经知道了,我问过使用猫鼬。谢谢谢天谢地,这很有效,但我决定改变我的模式,这样查询会更好更快!