我正在尝试将update
与upsert
一起使用,并提供我自己的_id
作为密钥。
事实证明,它仅在我使用insert
时有效,如果upsert:true
附带更新,则新插入的文档会获取Mongo自动生成的id
。
见下文:
PRIMARY> db.internal.update({_id: "my_id"},{ "value": "xyz"}, {upsert:true})
PRIMARY> db.internal.find()
{ "_id" : ObjectId("50c6cbb21d8b512bc0fe9576"), "value" : "xyz" }
PRIMARY> db.internal.insert({_id: "my_id2", "value": "xyz"})
PRIMARY> db.internal.find()
{ "_id" : ObjectId("50c6cbb21d8b512bc0fe9576"), "value" : "xyz" }
{ "_id" : "my_id2", "value" : "xyz" }
这是一个功能还是一个错误?
根据我在Mongo's docs中看到的,这将起作用
答案 0 :(得分:8)
是的,这是一个鲜为人知的问题。诀窍是使用带有upsert的$set
修饰符。然后它将组合您的更新和查询部分以形成上传文档。看:
db.internal.update({_id: "my_id"},{"$set": {"value": "xyz"}}, {upsert:true})
db.internal.find()
// { "_id" : "my_id", "value" : "xyz" }
答案 1 :(得分:0)
刚刚发现如果我在数据部分再次提供_id,除了条件部分之外,它还可以。
e.g。
PRIMARY> db.internal.update({_id: "my_id3"},{ _id: "my_id3", "value": "xyz"}, {upsert:true})
PRIMARY> db.internal.find()
{ "_id" : ObjectId("50c6cbb21d8b512bc0fe9576"), "value" : "xyz" }
{ "_id" : "my_id2", "value" : "xyz" }
{ "_id" : "my_id3", "value" : "xyz" }
但是,这似乎不是api意图 - 正如您在docs example中可以看到{ _id:7 }
与{ upsert:true }
一起提供
db.bios.update(
{
_id: 7,
name: { first: 'Ken', last: 'Thompson' }
},
{
$set: {
birth: new Date('Feb 04, 1943'),
contribs: [ 'UNIX', 'C', 'B', 'UTF-8' ],
awards: [
{
award: 'Turing Award',
year: 1983,
by: 'ACM'
},
{
award: 'IEEE Richard W. Hamming Medal',
year: 1990,
by: 'IEEE'
},
{
award: 'National Medal of Technology',
year: 1998,
by: 'United States'
},
{
award: 'Tsutomu Kanai Award',
year: 1999,
by: 'IEEE'
},
{
award: 'Japan Prize',
year: 2011,
by: 'The Japan Prize Foundation'
}
]
}
},
{ upsert: true }
)
答案 2 :(得分:0)
应该注意的是,没有$ set / $ pull / etc。修饰符,你只需用第二个参数替换文档。
> db.test.update({_id: 'foo'}, {_id: 'foo', value: 'xyz'}, upsert=true)
> db.test.find()
{ "_id" : "foo", "value" : "xyz" }
> db.test.update({_id: 'foo'}, {_id: 'foo', value: 'hello'}, upsert=true)
> db.test.find()
{ "_id" : "foo", "value" : "hello" }