找到你要的答案

Q:Mongoose: Upsert document with $sum

Q:Mongoose:美元和更新插入文档

Say I have a document that looks like this:

var TestSchema = new Schema({
    _id: String,
    userId: Number,
    date: Date,
    usage: Object
});

When I insert something into the database, that document can look like:

{
    userId: 10,
    date: 2015-11-12,
    usage: {
        foo: 12,
        bar: 5
    }
}

Now is it possible to upsert this document, where usage uses the $sum of the new document and the old document?

So when I do findOneAndUpdate, I basically only want to add up the usage.

说我有一个文件,看起来像这样:

var TestSchema = new Schema({
    _id: String,
    userId: Number,
    date: Date,
    usage: Object
});

当我在数据库中插入一些东西时,该文档可以看起来像:

{
    userId: 10,
    date: 2015-11-12,
    usage: {
        foo: 12,
        bar: 5
    }
}

现在可以更改插入此文件,在使用使用新文件和旧文件和美元?

所以当我findoneandupdate,我基本上只想加上使用。

answer1: 回答1:

The $sum operator is applicable only to the aggregation framework via the $group operator pipeline stage and can only return a sum on each grouped field (not multiple fields). What you need is the $add arithmetic operator and the specific operation you want can't be done with an atomic update, you'd need two operations to do this: an aggregation which adds up the old field with the new object and then the findOneAndUpdate operation.

Consider the following operations which will ultimately produce the desired update:

var newUsageObj = {
    "foo": 8,
    "bar": 15
},
query = { "userId": 10 };

// Using the mongoose aggregation builder
Model.aggregate()
     .match(query)
     .project({
         "updatedUsage": {
             "foo": { "$add": [ "$usage.foo", newUsageObj.foo ]},
             "bar": { "$add": [ "$usage.bar", newUsageObj.bar ]}
         })
     .exec(function (err, res){
         if (err) return handleError(err);
         res.forEach(function (doc){
             Model.findOneAndUpdate(query, { "usage": doc.updatedUsage }, options, callback);
         });
     });

Read the Aggregation docs for more information.

$和运算符仅适用于通过$组运算符流水线阶段的聚合框架,并且只能在每个分组字段(而不是多个字段)返回一个总和。你需要的是美元加算术运算符和你想要的具体操作,不能用一个原子的更新,你需要两个操作这样做:它加上了旧的领域与新的对象,然后findoneandupdate操作聚合。

考虑下面的操作,最终将产生所需的更新:

var newUsageObj = {
    "foo": 8,
    "bar": 15
},
query = { "userId": 10 };

// Using the mongoose aggregation builder
Model.aggregate()
     .match(query)
     .project({
         "updatedUsage": {
             "foo": { "$add": [ "$usage.foo", newUsageObj.foo ]},
             "bar": { "$add": [ "$usage.bar", newUsageObj.bar ]}
         })
     .exec(function (err, res){
         if (err) return handleError(err);
         res.forEach(function (doc){
             Model.findOneAndUpdate(query, { "usage": doc.updatedUsage }, options, callback);
         });
     });

阅读聚集文档获取更多的信息。

mongodb  mongoose