Javascript 失踪儿童

Javascript 失踪儿童,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,将Mongoose与MongoDB一起使用,我的模式如下: var PartSchema = new Schema({ partcode: String, children: [String] }); 数据如下所示: [{"partcode":"A1","children":["B1","B2","B3","B4"]}, {"partcode":"B1","children":["C11","C21","C31","C41"]}, {"partcode":"B3","chi

将Mongoose与MongoDB一起使用,我的模式如下:

var PartSchema = new Schema({
    partcode: String,
    children: [String]
});
数据如下所示:

[{"partcode":"A1","children":["B1","B2","B3","B4"]},
 {"partcode":"B1","children":["C11","C21","C31","C41"]},
 {"partcode":"B3","children":["C13","C23","C33","C43"]},
我可以使用以下静态调用查询A1的子字段:

PartSchema.static('getChildren', function (partcode, callback) {
    var self = this;
    self.findOne({ partcode: partcode }, childrenOnly)
        .exec(function (err, doc) {
        return self.find({"partcode": {"$in": doc.children} }, exclId, callback);
    });
});
此邮件返回(通过快递)

我需要返回所有未找到的子项,例如:

[{"children":["B2","B4"}]
您可以使用lodash库中的方法计算阵列集差异:

var _ = require("lodash");
PartSchema.static('getChildren', function (partcode, callback) {
    var self = this;
    self.findOne({ partcode: partcode }, childrenOnly)
        .exec(function (err, doc) {
        var promise = self.find({"partcode": {"$in": doc.children} }, exclId).lean().exec();
        promise.then(function (res){
             var codes = res.map(function (m) {
                 return m.children;
             }),
                 obj = {"children": _.difference(doc.children, codes)},
                 result = [];
             result.push(obj);
             return result;
        });
    });
});
--更新--

使用MongoDB的,您可以实现所需的结果。让我们先在mongoshell演示一下

假设在零件集合中插入以下测试文档:

db.part.insert([
    {"partcode":"A1","children":["B1","B2","B3","B4"]},
    {"partcode":"B1","children":["C11","C21","C31","C41"]},
    {"partcode":"B3","children":["C13","C23","C33","C43"]}
])
这里的聚合非常有用,因为您有一个给定partcode的子partcodes数组,比如说
“A1”
,即
[“B1”、“B2”、“B3”、“B4”]
。在此实例中,聚合管道将由以下聚合管道阶段组成:

  • -您需要此选项来筛选其子部件代码不在
    [“B1”、“B2”、“B3”、“B4”]
    数组中的文档。这是通过使用操作员来实现的

  • -这将对上一个流中的所有文档进行分组,并创建一个包含父零件代码的附加数组字段。通过使用蓄能器操作器使之成为可能

  • -通过添加新字段
    partcode
    (最终将成为结果对象的一部分)重塑流中的每个文档的形状,并抑制
    \u id
    字段。在这里,您可以获得条件中的父零件代码与管道文档中的父零件代码之间的数组差异,这可以使用set运算符实现

  • 最终的聚合操作符如下所示(使用mongoshell):

    输出

    /* 0 */
    {
        "result" : [ 
            {
                "partcode" : ["B2","B4"]
            }
        ],
        "ok" : 1
    }
    
    在Mongoose模式方法中使用相同的概念:

    PartSchema.static('getChildren', function (partcode, callback) {
        var self = this;
        self.findOne({ partcode: partcode }, childrenOnly)
            .exec(function (err, doc) {
                var pipeline = [        
                    {
                        "$match": {
                            "children": { "$nin": doc.children }
                        }
                    },
                    {
                        "$group": {
                            "_id": null,
                            "parents": {
                                "$addToSet": "$partcode"
                            }
                        }
                    },
                    {
                        "$project": {
                            "_id": 0,
                            "partcode": {
                                "$setDifference": [ doc.children, "$parents" ]
                            }
                        }
                    }
                ],
                self.aggregate(pipeline).exec(callback);                
        });
    });
    
    或者使用Mongoose进行流畅的通话:

    PartSchema.static('getMissedChildren', function (partcode, callback) {
        var self = this;
        self.findOne({ partcode: partcode }, childrenOnly)
            .exec(function (err, doc) {
                var promise = self.aggregate()
                    .match({"children": { "$nin": doc.children }})
                    .group({"_id": null,"parents": {"$addToSet": "$partcode"}})
                    .project({"_id": 0,"partcode": {"$setDifference": [ doc.children, "$parents" ]}})
                    .exec(callback);
                });
        });
    

    嗨,克里达姆,几乎是对的。
    result
    console.log
    显示`[{“children”:[“B2”,“B4”}``但原始调用显示一个mongoose对象(毫无疑问,其中嵌入了数据)。我认为express希望使用
    MongooseDocument
    格式,因此需要相反的格式,因为
    结果
    是JSON,应该是MongooseDocument。除了要求使用MongooseDocument格式之外,还需要做一些小的更改。
    返回m.partcode
    ,而不是
    返回m.children
    。聚合pipeline builder是一个非常优雅的解决方案。不幸的是,它仍然发出JSON而不是Mongodoc。@Terry Nice one!更新了工作解决方案,干杯:-)一篇标题为“失踪的孩子”的帖子…xD
    PartSchema.static('getChildren', function (partcode, callback) {
        var self = this;
        self.findOne({ partcode: partcode }, childrenOnly)
            .exec(function (err, doc) {
                var pipeline = [        
                    {
                        "$match": {
                            "children": { "$nin": doc.children }
                        }
                    },
                    {
                        "$group": {
                            "_id": null,
                            "parents": {
                                "$addToSet": "$partcode"
                            }
                        }
                    },
                    {
                        "$project": {
                            "_id": 0,
                            "partcode": {
                                "$setDifference": [ doc.children, "$parents" ]
                            }
                        }
                    }
                ],
                self.aggregate(pipeline).exec(callback);                
        });
    });
    
    PartSchema.static('getMissedChildren', function (partcode, callback) {
        var self = this;
        self.findOne({ partcode: partcode }, childrenOnly)
            .exec(function (err, doc) {
                var promise = self.aggregate()
                    .match({"children": { "$nin": doc.children }})
                    .group({"_id": null,"parents": {"$addToSet": "$partcode"}})
                    .project({"_id": 0,"partcode": {"$setDifference": [ doc.children, "$parents" ]}})
                    .exec(callback);
                });
        });