如何有条件地删除字段mongodb
How to remove field conditionally mongoodb
我有一个集合,其文档如下所示:
{
_id: ObjectId('111111111122222222223333'),
my_array: [
{
id: ObjectId('777777777788888888889999')
name: 'foo'
},
{
id: ObjectId('77777777778888888888555')
name: 'foo2'
}
//...
]
//more attributes
}
但是,有些文档有 my_array: [{}]
(其中一个元素是一个空数组)。
如何有条件地添加或删除投影?
我必须在查询结束时将它添加到 mongo 管道,并且我只想在它具有至少一个不是空对象的元素。如果有空对象,请将其删除。
我尝试在投影阶段使用 $cond
和 $eq
,但不支持。有什么解决这个问题的建议吗?
您不能在 query
中执行此操作,但是在聚合中,您可以将 $filter 添加到管道中,如下所示:
db.collection.aggregate([
{
$project: {
my_array: {
$filter: {
input: "$my_array",
as: "elem",
cond: {
$ne: [
{},
"$$elem"
]
}
}
}
}
}
])
然而,除非这是“正确”的行为,否则我建议您清理数据库,维护“正确”的结构比到处更新所有查询要简单得多。
您可以使用此更新删除这些对象:
db.collection.update({
"myarray": {}
},
[
{
"$set": {
"my_array": {
$filter: {
input: "$my_array",
as: "elem",
cond: {
$ne: [
{},
"$$elem"
]
}
}
}
}
},
],
{
"multi": false,
"upsert": false
})
假设您有这样的文档,其中包含 my_array
字段:
{ "my_array" : [ ] }
{ "my_array" : [ { "a" : 1 } ] } // #(1)
{ "my_array" : null }
{ "some_fld" : "some value" }
{ "my_array" : [ { } ] }
{ "my_array" : [ { "a" : 2 }, { "a" : 3 } ] } // #(2)
并且,以下聚合将进行过滤,结果将包含 两个 文档 (1)
和 (2)
:
db.collection.aggregate([
{
$match: {
$expr: {
$and: [
{ $eq: [ { $type: "$my_array" }, "array" ] },
{ $gt: [ { $size: "$my_array" }, 0 ] },
{ $ne: [ [{}], "$my_array" ] }
]
}
}
}
])
这也适用于 find
方法:
db.collection.find({
$expr: {
$and: [
{ $eq: [ { $type: "$my_array" }, "array" ] },
{ $gt: [ { $size: "$my_array" }, 0 ] },
{ $ne: [ [{}], "$my_array" ] }
]
}
})
要在文档为空时从文档中删除 my_array
字段,请尝试此聚合:
db.collection.aggregate([
{
$addFields: {
my_array: {
$cond: [
{$and: [
{ $eq: [ { $type: "$my_array" }, "array" ] },
{ $gt: [ { $size: "$my_array" }, 0 ] },
{ $ne: [ [{}], "$my_array" ] }
]},
"$my_array",
"$$REMOVE"
]
}
}
}
])
结果:
{ }
{ "my_array" : [ { "a" : 1 } ] }
{ }
{ "a" : 1 }
{ }
{ "my_array" : [ { "a" : 2 }, { "a" : 3 } ] }
我有一个集合,其文档如下所示:
{
_id: ObjectId('111111111122222222223333'),
my_array: [
{
id: ObjectId('777777777788888888889999')
name: 'foo'
},
{
id: ObjectId('77777777778888888888555')
name: 'foo2'
}
//...
]
//more attributes
}
但是,有些文档有 my_array: [{}]
(其中一个元素是一个空数组)。
如何有条件地添加或删除投影?
我必须在查询结束时将它添加到 mongo 管道,并且我只想在它具有至少一个不是空对象的元素。如果有空对象,请将其删除。
我尝试在投影阶段使用 $cond
和 $eq
,但不支持。有什么解决这个问题的建议吗?
您不能在 query
中执行此操作,但是在聚合中,您可以将 $filter 添加到管道中,如下所示:
db.collection.aggregate([
{
$project: {
my_array: {
$filter: {
input: "$my_array",
as: "elem",
cond: {
$ne: [
{},
"$$elem"
]
}
}
}
}
}
])
然而,除非这是“正确”的行为,否则我建议您清理数据库,维护“正确”的结构比到处更新所有查询要简单得多。
您可以使用此更新删除这些对象:
db.collection.update({
"myarray": {}
},
[
{
"$set": {
"my_array": {
$filter: {
input: "$my_array",
as: "elem",
cond: {
$ne: [
{},
"$$elem"
]
}
}
}
}
},
],
{
"multi": false,
"upsert": false
})
假设您有这样的文档,其中包含 my_array
字段:
{ "my_array" : [ ] }
{ "my_array" : [ { "a" : 1 } ] } // #(1)
{ "my_array" : null }
{ "some_fld" : "some value" }
{ "my_array" : [ { } ] }
{ "my_array" : [ { "a" : 2 }, { "a" : 3 } ] } // #(2)
并且,以下聚合将进行过滤,结果将包含 两个 文档 (1)
和 (2)
:
db.collection.aggregate([
{
$match: {
$expr: {
$and: [
{ $eq: [ { $type: "$my_array" }, "array" ] },
{ $gt: [ { $size: "$my_array" }, 0 ] },
{ $ne: [ [{}], "$my_array" ] }
]
}
}
}
])
这也适用于 find
方法:
db.collection.find({
$expr: {
$and: [
{ $eq: [ { $type: "$my_array" }, "array" ] },
{ $gt: [ { $size: "$my_array" }, 0 ] },
{ $ne: [ [{}], "$my_array" ] }
]
}
})
要在文档为空时从文档中删除 my_array
字段,请尝试此聚合:
db.collection.aggregate([
{
$addFields: {
my_array: {
$cond: [
{$and: [
{ $eq: [ { $type: "$my_array" }, "array" ] },
{ $gt: [ { $size: "$my_array" }, 0 ] },
{ $ne: [ [{}], "$my_array" ] }
]},
"$my_array",
"$$REMOVE"
]
}
}
}
])
结果:
{ }
{ "my_array" : [ { "a" : 1 } ] }
{ }
{ "a" : 1 }
{ }
{ "my_array" : [ { "a" : 2 }, { "a" : 3 } ] }