示例文档:
{
_id: 42,
foo: {
bar: [1, 2, 3, 3, 4, 5, 5]
}
}
查询:
我想要“从foo.bar
中删除所有$lt: 4
的条目和第一个匹配$eq: 5
的条目”。重要提示:$eq
部分必须仅删除单个条目!
我有一个可行的解决方案,使用了3个更新查询,但对于这个简单的任务来说太多了。尽管如此,以下是我迄今为止所做的:
1. 查找第一个匹配$eq: 5
的条目,并将其$unset
。(正如您所知:$unset
不会将其删除,而只是将其设置为null
):
update(
{ 'foo.bar': 5 },
{ $unset: { 'foo.bar.$': 1 } }
)
2. 使用$pull
删除所有值为null
的条目,以确保先前的5
确实被删除:
update(
{},
{ $pull: { 'foo.bar': null } }
)
3. 使用$pull
命令删除所有小于4的记录:
update(
{},
{ $pull: { 'foo.bar': { $lt: 4 } } }
)
生成的文档:
{
_id: 42,
foo: {
bar: [4, 5]
}
}
思路和想法:
扩展查询1.,使其
$unset
条目$lt: 4
和一个条目$eq: 5
。然后我们可以执行查询2.,没有必要进行查询3.。扩展查询2.,将匹配
$or: [{$lt: 4}, {$eq: 5}]
的所有内容都$pull
掉。然后就没有必要进行查询3.。扩展查询2.,将所有不匹配
$not: { $gte: 4 }
的内容都$pull
掉。这个表达式应该匹配$lt: 4
和$eq: null
。
我已经尝试实现这些查询,但有时它会抱怨查询语法,有时查询确实执行了,但什么也没删除。
如果有人有解决此问题的有效方法,那就太好了。
$lt: 4
或$eq: 5
,那么以下是一些例子:[] -> []
,[2] -> []
,[4] -> [4]
,[5] -> []
,[1,1,2,2,3,4,4] -> [4,4]
,[1,4,5,5,5] -> [4,5,5]
,[3,5] -> []
。换句话说:“每个小于4的条目和一个等于5的条目(如果有任何等于5的条目)”。 - Benjamin M$in
的查询无法工作,因为在我的真实场景中,这些数字是ISODates
,我需要使用$lt
才能使其工作 :( - Benjamin M$in
进行精确匹配(因为$in
不接受$lt
选项)的情况下,您最好采用目前正在使用的方法。您也不能执行`{“$pull”:{“foo.bar”:{“$lt”:4,“$gte”:null}}},因为那是一个and条件,不会匹配任何内容。一些人可能会发现这里的分析和结论有用。 - Blakes Seven