Mongodb 对空数组使用$push
我有一个mongo文档,它有一个名为events的数组字段 此字段有时可以为空 我使用$push将元素添加到事件数组中。问题是,当events字段为null时,它无法工作 例如,如果在数据库中,它如下所示:Mongodb 对空数组使用$push,mongodb,Mongodb,我有一个mongo文档,它有一个名为events的数组字段 此字段有时可以为空 我使用$push将元素添加到事件数组中。问题是,当events字段为null时,它无法工作 例如,如果在数据库中,它如下所示: { "_id" : ObjectId("4d2d8deff4e6c1d71fc29a07"), "user_id" : "714638ba-2e08-2168-2b99-00002f3d43c0", "
{
"_id" : ObjectId("4d2d8deff4e6c1d71fc29a07"),
"user_id" : "714638ba-2e08-2168-2b99-00002f3d43c0",
"events" : null
}
我使用$push运行更新:
{ $push : { "events" : { "profile" : 10, "data" : "X"}}};
它将失败,因为事件为null
我可以通过查询数据库的两个步骤来解决这个问题。但是,我可以在1个查询中完成吗
如果数组字段不为null,我想将事件添加到数组中,但如果为null,则首先创建事件空数组,然后将事件添加到数组中。不要为没有数据的字段写入null值。然后您将能够以预期的方式使用$push:
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.insert({a:1})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.update({a:1},{$push:{b:[1]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.find()
{ "_id" : ObjectId("5f0b481dd9c782d95389a1ce"), "a" : 1, "b" : [ [ 1 ] ] }
如果坚持将空值写入数据库,则可以使用聚合管道更新和$set、$ifNull、$concatarray和$merge:
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.insert({a:2,b:null})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.find()
{ "_id" : ObjectId("5f0b4bfbd9c782d95389a1d2"), "a" : 2, "b" : null }
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$match:{a:2}},{$set:{b:{$ifNull:[{$concatArrays:['$b',[4]]},[4]]}}},{$merge:'foo'}])
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.find()
{ "_id" : ObjectId("5f0b4bfbd9c782d95389a1d2"), "a" : 2, "b" : [ 4 ] }
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$match:{a:2}},{$set:{b:{$ifNull:[{$concatArrays:['$b',[5]]},[5]]}}},{$merge:'foo'}])
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.find()
{ "_id" : ObjectId("5f0b4bfbd9c782d95389a1d2"), "a" : 2, "b" : [ 4, 5 ] }
不要为没有数据的字段写入空值。然后您将能够以预期的方式使用$push:
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.insert({a:1})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.update({a:1},{$push:{b:[1]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.find()
{ "_id" : ObjectId("5f0b481dd9c782d95389a1ce"), "a" : 1, "b" : [ [ 1 ] ] }
如果坚持将空值写入数据库,则可以使用聚合管道更新和$set、$ifNull、$concatarray和$merge:
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.insert({a:2,b:null})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.find()
{ "_id" : ObjectId("5f0b4bfbd9c782d95389a1d2"), "a" : 2, "b" : null }
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$match:{a:2}},{$set:{b:{$ifNull:[{$concatArrays:['$b',[4]]},[4]]}}},{$merge:'foo'}])
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.find()
{ "_id" : ObjectId("5f0b4bfbd9c782d95389a1d2"), "a" : 2, "b" : [ 4 ] }
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$match:{a:2}},{$set:{b:{$ifNull:[{$concatArrays:['$b',[5]]},[5]]}}},{$merge:'foo'}])
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.find()
{ "_id" : ObjectId("5f0b4bfbd9c782d95389a1d2"), "a" : 2, "b" : [ 4, 5 ] }
你可以使用MogoDB 4.2。这允许作为单个操作执行更新
var OBJ_TO_ADD = { "profile": 10, "data": "X" }
db.test.updateOne(
{ "_id" : ObjectId("4d2d8deff4e6c1d71fc29a07") },
[
{
$set: {
events: {
$ifNull: [
{ $concatArrays: [ "$events", [ OBJ_TO_ADD ] ] },
[ OBJ_TO_ADD ]
]
}
}
}
]
)
你可以使用MogoDB 4.2。这允许作为单个操作执行更新
var OBJ_TO_ADD = { "profile": 10, "data": "X" }
db.test.updateOne(
{ "_id" : ObjectId("4d2d8deff4e6c1d71fc29a07") },
[
{
$set: {
events: {
$ifNull: [
{ $concatArrays: [ "$events", [ OBJ_TO_ADD ] ] },
[ OBJ_TO_ADD ]
]
}
}
}
]
)
事件不能是空数组而不是空数组吗?这应该更一致。问题是,我不知道events字段是否不存在,或者有时也可能为null:/这不是一个修正字段。。尽管我同意处理这个问题的最佳方法,但就是始终创建它,即使它是空的。你能不能用空数组代替空数组?这应该更一致。问题是,我不知道events字段是否不存在,或者有时也可能为null:/这不是一个修正字段。。尽管我同意处理这个问题的最好方法,就是总是创建它,即使它是空的