我想添加一个文件,如果它不存在,或者在其中一个子文档中添加一个元素。
db.test.update(
{
name : 'Peter'
},
$setOnInsert : {
name : 'Peter',
visits: { 'en' : ['today'], 'us' : [] }
},
$push : {
visits.en : 'today'
},
{ upsert : true }
)
如果存在Peter
,请在其visists.en
或visists.us
数组中添加元素。否则,为Peter
创建一个文档。该文档应具有visits
的格式,该格式应包含当前元素('today'
)。
我的问题是我有"have conflicting mods in update"
。
即(afaik),我不能在一个查询中写两件事。但我怎样才能解决这个难题?
答案 0 :(得分:7)
您可以在没有$setOnInsert
运算符的情况下实现它。
db.test.update(
{
name : 'Peter'
},
{
$push : {
"visits.en" : 'today'
}
},
{ upsert : true }
)
如果Peter存在,则元素'today'
将添加到其visits.en
数组中。否则,将为Peter创建一个文档,其中包含visits
对象,该文档将包含带有en
元素的数组'today'
。
我认为,由于您在两个操作(visits
和$setOnInsert
)中使用相同的属性($push
),因此发生了错误。
答案 1 :(得分:0)
您仍然可以使用$setOnInsert
,但$setOnInsert
和$push
未在与之前提及的相同字段中更新。
N.b:如果您不想在数组中使用重复值,我们会使用$addToSet
db.test.update(
{
name : 'Peter'
},
{
$setOnInsert: {name : 'Peter'},
$addToSet: {"visits.en": 'today'} // or $push
},
{upsert: true})
来自Node.js :我这样做,但你仍然可以直接使用查询。
我这样做的原因是不要使用错误的字段名称插入记录并组织我的更新查询。
首先,您需要创建架构的实例。
var testSchema = require(./path/testSchema.js); // require your schema
var test = conn.model("test", testSchema, "test"); //conn is the mongoose connection object to the DB
var testToCreate = new test();
testToCreate.name : 'Peter' //add fields to the instance
var testToUpsert = testToCreate.toObject();
delete testToUpsert._id;
delete testToUpsert.visits;
其次,在为模式创建实例时,默认情况下会生成_id属性并且它是唯一的,因此我们需要将其从实例中删除,以便$setOnInsert
函数正确,我们删除了访问数组将$addToSet
(或$push
)与$setOnInsert
一起使用时,有两个影响同一字段的查询。
var options = {
upsert: true
};
test.update({
name : 'Peter'
}, {
$setOnInsert: testToUpsert,
$addToSet: {
"visits.en":'today'
}
},
options,
function(err, testAffected) {
if (err) {
return console.error(err);
}
console.log('testAffected! :', testAffected);
});