mongodb $ elemMatch与regex仅返回单个文档数组中的一个元素

时间:2018-09-25 12:48:33

标签: mongodb

我想要在嵌套数组中搜索字符串。对于每个文档,尽管文档中存在更多匹配的数组元素,但它仅返回第一个匹配的数组元素。 Mongo结构:

{
"bookmarkId" : "5b9ce0be489cdc34ffa9d650",
"notes" : [
    {
        "noteId" : "5b9ce0be489cdc34ffa9d650",
        "note" : "number"
    },
    {
        "noteId" : "5b9ce4ba489cdc34ffa9d653",
        "note" : "hhgjjkg"
    },
    {
        "noteId" : "5b9ce4cc489cdc34ffa9d654",
        "note" : "test"
    },
    {
        "noteId" : "5b9ce8a2a3219b3f166cc5de",
        "note" : "hhgjjkg"
    },
    {
        "noteId" : "5b9cf703a3219b3f166cc5ea",
        "note" : "number"
    }
],
"userId" : "5aeae1da9072420ff68bd48e"
}

mongodb查询为:

db.bookmark.find({"userId" : "5aeae1da9072420ff68bd48e","notes.note":new RegExp('hgjj', 'i')},{_id:0,bookmarkId:1,notes:{$elemMatch:{note:new RegExp('hgjj', 'i')}}})

尽管第2个和第4个元素与查询匹配,但它仅返回第一个元素。 输出:

{ "bookmarkId" : "5b9ce0be489cdc34ffa9d650", "notes" : [ { "noteId" : "5b9ce4ba489cdc34ffa9d653", "note" : "hhgjjkg" } ] }

如何从mongodb获取所有匹配的元素?

2 个答案:

答案 0 :(得分:1)

根据find projection的mongoDB文档,您不能使用$ elemMatch来过滤元素。

相反,您可以考虑使用聚合:

db.bookmark.aggregate([
{
    $unwind: '$notes'
},
{
    $match: {"userId" : "5aeae1da9072420ff68bd48e","notes.note":new RegExp('hgjj', 'i')}
},
{
    $group: {
        _id: '$bookmarkId',
        notes: {$push : '$notes'}
     }
},
{
    $project: {
        _id: 0,
        bookmarkId: '$_id',
        notes: '$notes'
     }
}])

答案 1 :(得分:0)

参见此处:question

  

定义$ elemMatch :   $ elemMatch运算符限制了以下内容   查询结果中的一个字段,仅包含第一个   符合$ elemMatch条件的元素。

因此,如果您使用elemMatch运算符计算投影,则将仅投影嵌套数组中匹配的第一个元素。

在我看来,您似乎想创建一个仅包含匹配的嵌套文档的新“ notes”数组。一种方法是通过聚合框架进行分组:

db.bookmark.aggregate([
{
    "$match": {
        "userId" : "5aeae1da9072420ff68bd48e",
        "notes.note":new RegExp('hgjj', 'i')
    }        
}, 
{
    "$unwind": {
        "path": "$notes"
    }
}, 
{
    "$match": {
        "notes.note": new RegExp('hgjj', 'i')
    }
}, 
{
    "$group": {
        "_id": "$_id",
        "bookmark_id": {
            "$first": "$bookmarkId"
        },
        "notes": {
            "$push": "$notes"
        }        
    }
},
{
    "$project": {
        "_id": 0,
        "bookmark_id": 1,
        "notes": 1
    }
}
])

产量:

{ "bookmark_id" : "5b9ce0be489cdc34ffa9d650", "notes" : [ { "noteId" : "5b9ce4ba489cdc34ffa9d653", "note" : "hhgjjkg" } ] }
{ "bookmark_id" : "5b9ce0be489cdc34ffa9d650", "notes" : [ { "noteId" : "5b9ce8a2a3219b3f166cc5de", "note" : "hhgjjkg" } ] }
{ "bookmark_id" : "5b9ce0be489cdc34ffa9d650", "notes" : [ { "noteId" : "5b9ce4ba489cdc34ffa9d653", "note" : "hhgjjkg" }, { "noteId" : "5b9ce8a2a3219b3f166cc5de", "note" : "hhgjjkg" } ] }