sql >> データベース >  >> NoSQL >> MongoDB

マングースの再帰的な人口

    今すぐこれを行うことができます(https://www.mongodb.com/blog/post/introducing-version-40-mongoose-nodejs-odmを使用)

    var mongoose = require('mongoose');
    // mongoose.Promise = require('bluebird'); // it should work with native Promise
    mongoose.connect('mongodb://......');
    
    var NodeSchema = new mongoose.Schema({
        children: [{type: mongoose.Schema.Types.ObjectId, ref: 'Node'}],
        name: String
    });
    
    var autoPopulateChildren = function(next) {
        this.populate('children');
        next();
    };
    
    NodeSchema
    .pre('findOne', autoPopulateChildren)
    .pre('find', autoPopulateChildren)
    
    var Node = mongoose.model('Node', NodeSchema)
    var root=new Node({name:'1'})
    var header=new Node({name:'2'})
    var main=new Node({name:'3'})
    var foo=new Node({name:'foo'})
    var bar=new Node({name:'bar'})
    root.children=[header, main]
    main.children=[foo, bar]
    
    Node.remove({})
    .then(Promise.all([foo, bar, header, main, root].map(p=>p.save())))
    .then(_=>Node.findOne({name:'1'}))
    .then(r=>console.log(r.children[1].children[0].name)) // foo
    

    マングースなしの単純な代替手段:

    function upsert(coll, o){ // takes object returns ids inserted
        if (o.children){
            return Promise.all(o.children.map(i=>upsert(coll,i)))
                .then(children=>Object.assign(o, {children})) // replace the objects children by their mongo ids
                .then(o=>coll.insertOne(o))
                .then(r=>r.insertedId);
        } else {
            return coll.insertOne(o)
                .then(r=>r.insertedId);
        }
    }
    
    var root = {
        name: '1',
        children: [
            {
                name: '2'
            },
            {
                name: '3',
                children: [
                    {
                        name: 'foo'
                    },
                    {
                        name: 'bar'
                    }
                ]
            }
        ]
    }
    upsert(mycoll, root)
    
    
    const populateChildren = (coll, _id) => // takes a collection and a document id and returns this document fully nested with its children
      coll.findOne({_id})
        .then(function(o){
          if (!o.children) return o;
          return Promise.all(o.children.map(i=>populateChildren(coll,i)))
            .then(children=>Object.assign(o, {children}))
        });
    
    
    const populateParents = (coll, _id) => // takes a collection and a document id and returns this document fully nested with its parents, that's more what OP wanted
      coll.findOne({_id})
        .then(function(o){
          if (!o.parent) return o;
          return populateParents(coll, o.parent))) // o.parent should be an id
            .then(parent => Object.assign(o, {parent})) // replace that id with the document
        });
    


    1. NodeJSのMongoデータベースに挿入されたドキュメントの_idを取得します

    2. モジュール'../build/Release/bson']コードが見つかりません:'MODULE_NOT_FOUND'} js-bson:純粋なJSバージョンを使用してc++bson拡張機能を読み込めませんでした

    3. 集計で機能しない_idを使用して検索

    4. さまざまなNoSQLデータベースのクイックリファレンスガイド