相当于匹配的子文档的捕获组

时间:2016-11-24 20:20:30

标签: javascript mongodb meteor

我有一个Chats集合,其参与者子文档就是这样..

{ 
    _id: '1',
    participants: [ { _id: 'A', seen: false },  { _id: 'B', seen: false } ],
    messages: []
}

只有2个参与者,其中一个是currentUser。我不知道哪个。此外,任何一对用户只能进行一次聊天。

为了找到聊天,我使用了两个用户ID。所以查找查询如下所示:

Chats.find( 
    {   $and: [ 
        { participants: {$elemMatch: {_id: otherUserId}}}, 
        { participants: {$elemMatch: {_id: currentUserId}}} 
    ]}
)

我想允许currentUser在一次更新操作中更新自己的seen字段。

目前我必须首先找到聊天,确定两个用户的哪个索引是currentUser,然后构建一个文档来更新该用户并在单独的操作中更新它。

是否有类似于正则表达式捕获组的东西,所以我可以知道与currentUserId匹配的元素的id?可能就像这样......

Chats.update(   {   $and: [ 
        { participants: {$elemMatch: {_id: otherUserId}}}, 
        { participants: capture({$elemMatch: {_id: currentUserId}})} 
    ]},  
    {   
        $set: {"participants.(capture[0]).seen": true}
    })

或者有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

这可能不是您正在寻找的解决方案,但我认为我应该建议它以防万一。

Chats.update(   {   $and: [ 
    { participants: {$elemMatch: {_id: otherUserId}}}, 
    { participants: {$elemMatch: {_id: currentUserId}}} 
]},  
{   
    $set: {"participants.$.seen": true}
})

这对你有用,因为$ elemMatch存储了匹配数组的索引。作为您的$ eleMatch,它将存储与最后一个$ eleMatch匹配的索引,该最后一个$ eleMatch将是您案例中的当前用户。因此,当您使用位置opertor时,它将更新当前用户的看到字段。

答案 1 :(得分:1)

一种轻松更新“看过”的简单方法。状态将是这样构建数据:

{
    _id: '1',
    participants: [ 'A', 'B'],
    seen: [],
    messages: []

}

然后你可以更新' A'看到过这样的信息:

Chats.update(
  { $and: [ {participants: 'A'}, {participants: 'B'} ] },
  { $addToSet: { seen: 'A' } }
)
    如果您只有一个查询,则不需要
  • $elemMatch 里面的条件
  • $addToSet只会添加' A'如果没有 已经存在。