Запрос MongoDB не возвращает результатов - PullRequest
0 голосов
/ 05 июля 2018

Я новичок в Монго и пытаюсь сделать очень простой запрос в этой коллекции:

{
    "_id" : ObjectId("gdrgrdgrdgdr"),
    "administrators" : {
        "-HGFsfes" : {
            "name" : "Jose",
            "phone" : NumberLong(124324)
        },
        "-HGFsfqs" : {
            "name" : "Peter",
            "phone" : "+43242342"
        }
    },
    "countries" : {
        "-dgfgrdg : {
            "lang" : "en",
            "name" : "Canada"
        },
        "-grdgrdg" : {
            "lang" : "en",
            "name" : "USA"
        }
    }
}

Как мне сделать запрос, который возвращает результаты администраторов с именем, например, "% Jos%".

То, что я делал до сих пор, таково: db.getCollection('coll').find({ "administrators.name": /Jos/});

И вариации этого. Но все, что я пробовал, возвращает ноль результатов.

Что я делаю не так?

Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 05 июля 2018

Ваша ошибка в том, что администраторы - это не массив, а объект с полями, которые сами являются объектами с полем имени. Правильный запрос будет

{ "administrators.-HGFsfes.name": /Jos/}

К сожалению, таким образом вы запрашиваете только поле имени -HGFsfes, а не другое поле имени администратора.

Чтобы достичь того, что вы хотите, единственное, что нужно сделать, это заменить объект администратора на массив, чтобы ваш документ выглядел так:

    { 
    "administrators" : [
        {
            "id" : "-HGFsfes", 
            "name" : "Jose", 
            "phone" : 124324
        }, 
        {
            "id" : "-HGFsfqs", 
            "name" : "Peter", 
            "phone" : "+43242342"
        }
    ], 
 countries : ...
}

Таким образом, ваш запрос будет работать.

НО вернет документы, где хотя бы одна запись в массиве администраторов имеет совпадающее поле имени. Чтобы вернуть только соответствующий элемент администратора, а не весь документ, проверьте этот вопрос и мой ответ для конвейера раскручивания / сопоставления / объединения групп.

0 голосов
/ 06 июля 2018

Хорошо, думаю, я нашел для вас лучшее решение с интегрированной структурой. Выполните следующий запрос к вашей текущей коллекции, и вы получите всех администраторов с именем «LIKE» jos (без учета регистра с параметром i):

db.test1.aggregate(
    [
        {
            $project: {
              administrators:{    $objectToArray: "$administrators"}
            }
        },
        {
            $unwind: {
                path : "$administrators"
            }
        },
        {
            $replaceRoot: {
            newRoot:"$administrators"
            }
        },
        {
            $match: {
            "v.name":/jos/i
            }
        },
    ]
);

выход

{ 
    "k" : "-HGFsfes", 
    "v" : {
        "name" : "Jose", 
        "phone" : NumberLong(124324)
    }
}

«k» и «v» поступают из оператора «$ objectToArray» , вы можете добавить $ project stage , чтобы переименовать их (или отменить, если значение k не материя)

Не уверен для тестирования Robomongo, но в Studio 3T, ранее Robomongo, вы можете скопировать / вставить этот запрос в консоли Intellishell или скопировать / импортировать на вкладке агрегации (маленький значок «вставить из буфера обмена»).

Надеюсь, это поможет.

0 голосов
/ 05 июля 2018

Вам нужно использовать запрос как этот:

db.collection_name.find({})

Так что если имя вашей коллекции - coll, то это будет:

db.coll.find({"administrators.-HGFsfes.name": /Jos/});

Посмотрите этот для того же запроса в монго.

Кроме того, попробуйте с шаблоном регулярного выражения, как это:

db.coll.find({"administrators..-HGFsfes.name": {"$regex":"Jos", "$options":"i"}}});

Это даст вам только один результат, потому что ваши данные не являются массивом, как показано ниже на скриншоте: enter image description here

Если вы хотите получить несколько результатов, вам необходимо реструктурировать данные.

...