'冻结'mongoose subdocs

时间:2014-02-11 20:25:24

标签: node.js mongodb mongoose

我的设置类似于:

B.js

var schemaB = new mongoose.Schema({
  x: Number,
  ...
});
module.exports = mongoose.model('B', schemaB);

A.js

var schemaA = new mongoose.Schema({
  b: {type: mongoose.Schema.Types.ObjectId, ref: 'B'},
  ...
});
module.exports = mongoose.model('A', schemaA);

有了这个,我的B文档就会发生变化,当我使用populate()检索A文档时,这些更改将反映在路径b的对象中}。

但是,某个b文档的路径A上的文档“冻结”是否存在?类似的东西:

var id=1;
A.findById(id).populate('b').exec(function(err, a) {
  if (err) return handleErr(err);

  console.log(a.b.x);
  // prints 42

  a.freeze('b') // fictitious freeze() fn
  b.x=20;

  b.save(function(err, b) {
    if (err) return handleErr(err);

    console.log(b.x);
    // prints 20

    A.findById(id).populate('b').exec(function(err, a) {
       if (err) return handleErr(err);

       console.log(a.b.x);
       // prints 42

    }); 
  });
});

1 个答案:

答案 0 :(得分:1)

没有上下文我不完全确定你为什么需要。似乎应该从更高的层面看问题?

我知道的一件事是toJSON功能。它剥离了Mongoose元数据和逻辑,并为您提供了一个普通的JS对象。除非您更改它,否则此对象不会更改。然后,您可以将此对象作为a的单独属性添加到b

// A.js

var schemaA = new mongoose.Schema({
    b: {type: mongoose.Schema.Types.ObjectId, ref: 'B'},
    frozenB: {}
    ...
});

// app.js

var id=1;
A.findById(id).populate('b').exec(function(err, a) {
    if (err) return handleErr(err);

    console.log(a.b.x);
    // prints 42

    a.frozenB = a.b.toJSON(); // Creates new object and assigns it to secondary property

    a.save(function (err, a) {
        b.x=20;

        b.save(function(err, b) {
            if (err) return handleErr(err);

            console.log(b.x);
            // prints 20

            A.findById(id).populate('b').exec(function(err, a) {
                if (err) return handleErr(err);

                console.log(a.frozenB);
                // prints 42

            }); 
        });
    });
});

编辑 - 如果您需要frozenB成为完整的mongoose文档,那么只需执行相同的操作即可将其作为新文档。

// A.js

var schemaA = new mongoose.Schema({
    b: {type: mongoose.Schema.Types.ObjectId, ref: 'B'},
    frozenB: {type: mongoose.Schema.Types.ObjectId, ref: 'B'}
    ...
});

// app.js

var id=1;
A.findById(id).populate('b').exec(function(err, a) {
    if (err) return handleErr(err);

    console.log(a.b.x);
    // prints 42

    var frozenB = a.b;
    delete frozenB._id; // makes it a new document as far as mongoose is concerned.
    frozenB.save(function (err, frozenB) {
        if (err) return handleErr(err);

        a.frozenB = frozenB;

        a.save(function (err, a) {
            b.x=20;

            b.save(function(err, b) {
                if (err) return handleErr(err);

                console.log(b.x);
                // prints 20

                A.findById(id).populate('b').exec(function(err, a) {
                    if (err) return handleErr(err);

                    console.log(a.frozenB);
                    // prints 42

                });
            }); 
        });
    });
});