Mongodb 在数组中拉数组
类似于,但我正在尝试拉它Mongodb 在数组中拉数组,mongodb,meteor,mongodb-query,Mongodb,Meteor,Mongodb Query,类似于,但我正在尝试拉它 db.getCollection('users').find({'favorites':{$elemMatch:{0:5719}}}, {"favorites.$": 1}) 返回以下内容: { "_id" : "FfEj5chmviLdqWh52", "favorites" : [ [ 5719, "2016-03-21T17:46:01.441Z", "
db.getCollection('users').find({'favorites':{$elemMatch:{0:5719}}}, {"favorites.$": 1})
返回以下内容:
{
"_id" : "FfEj5chmviLdqWh52",
"favorites" : [
[
5719,
"2016-03-21T17:46:01.441Z",
"a"
]
]
}
即使在这之后返回1:
Meteor.users.update(this.userId, {$pull: {'favorites':{$elemMatch:{0:movieid}}}})
它不起作用,因为正在尝试从“收藏夹”
数组中删除匹配的元素。您要做的是从收藏夹的数组内的数组中删除
为此,您需要一个位置匹配来指向nth
内部元素,然后使用一个非常小心的$pull
表达式来实际删除该元素:
Meteor.users.update(
{“收藏夹”:{“$elemMatch”:{“$elemMatch”:{“$eq”:5719}}},
{“$pull”:{“收藏夹.$”:5719}
)
带运算符的“double”比{0:5719}
更具表现力,因为它并没有“锁定”到第一个位置,而是实际查看匹配值。但是,如果你必须这样写,或者如果你“真的想”只在第一个位置匹配这个值,你可以这样写
请注意,从参数中的匹配返回的“索引”实际上是“外部”数组的索引。所以要从
当然,如果其中只有一个嵌套的数组元素,那么您不妨编写:
{“$pull”:{“favorites.0”:5719}
使用直接的“第一个索引”位置,因为您知道内部数组将始终存在
无论哪种情况,对象都会正确更新:
{
“_id”:“ffej5chmvilldqwh52”,
“收藏夹”:[
[
“2016-03-21T17:46:01.441Z”,
“a”
]
]
}
如果试图从收藏夹中
$pull
整个数组条目,则只需拨回$eleMatch
一个元素即可:
Meteor.users.update(
{“\u id”:this.userId},
{“$pull”:{“收藏夹”:{“$elemMatch”:{“$eq”:5719}}}
)
甚至:
Meteor.users.update(
{“\u id”:this.userId},
{“$pull”:{“收藏夹”:{“$elemMatch”:{“0”:5719}}
)
注意到:
{“\u id”:this.userId},
是我们通常用作“查询”选择器的长格式,尤其是当我们需要文档的\u id
以外的“条件”时。MiniMongo语句要求“至少”文档的\u id
语句的其余部分有一个“less”$elemMatch
,因为$pull
已经应用于数组
从外部数组中删除整个匹配元素的步骤:
{
“_id”:“ffej5chmvilldqwh52”,
“收藏夹”:[]
}
这是我发现的第一个真正有效的代码:
Meteor.users.update(Meteor.userId(), {$pull: {favorites: {$in: [i]}}})
显然,$in
进行了部分匹配。它似乎比工作代码更安全:
谢谢,但我想删除所有(理想情况下是一个)具有指定ID的收藏夹(收藏夹的第一个元素)。@Ceestimerman那么这怎么不是答案呢?那怎么不是你问的?第一个元素已被删除。我要查找的ID是收藏夹的第一个元素,应该从收藏夹数组中删除整个收藏夹。您的短代码没有删除收藏夹(也没有删除收藏夹中的ID),您的长代码告诉我:
MongoError:favorites中以美元($)为前缀的字段“$elemMatch”。$elemMatch”对存储无效。
错误来自包含this.userId,
-这安全吗?@Ceestimerman理解你现在要做什么。添加了正确的更新和解释。为什么会更安全?实际上,这是一个令人恼火的问题,因为太多人使用$in
,因为他们“认为”在匹配数组时必须使用它。用例实际上是相反的,您提供的“参数数组”可能与属性匹配。根据匹配的单个条件删除元素后,将执行以下操作。我不明白为什么一个“数组”能清楚或安全地说明这一点。代码似乎很模糊。似乎应该考虑到这个位置,但我从文档中了解到,它的作用与您的代码相同。那么,为什么要提交一个“答案”,说明您认为它在任何方面都更安全或更好呢?当你的问题没有这样的陈述时,你不能说“我一直都知道”。事实上,你的问题是,“我不知道怎么做”,然后有人很好地告诉你。考虑到误导性的标题和所有内容。您最初只回答了标题,最后一位代码与我问题中的非功能代码相同,带走了我的接受。我的回答清楚地说明了工作守则。只有在那段代码之后,我才在你的长篇回答中发现,你建议的$eq
同样有效。你仍然得到了我的赞成票。它不一样,我清楚地说明了区别(即在$pull
中不需要两个$elemMatch
,因为它已经作用于一个数组),当然它确实按照描述移除了元素。不管怎么说,这似乎是在胡思乱想$eq
查找单个值的相等性,$in
表示要测试列表中提供的“任意”相等性的值列表。所以它只是一个代码的副本,将一个操作符插入另一个操作符。两者都有效。
Meteor.users.update(
{ "_id": this.userId },
{ "$pull": { "favorites": { "$elemMatch": { "$eq": i } } } }
)