mongodb $ elemMatch с регулярным выражением возвращает только один элемент из массива одного документа - PullRequest
0 голосов
/ 25 сентября 2018

Я хочу поиск строки во вложенном массиве.Для каждого документа он возвращает только первый соответствующий элемент массива, хотя в документе есть более соответствующий элемент массива.Структура 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 голосов
/ 25 сентября 2018

См. Здесь: https://docs.mongodb.com/manual/reference/operator/projection/elemMatch/

Определение $ 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" } ] }
0 голосов
/ 25 сентября 2018

На основании документации 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'
     }
}])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...