Как получить элемент с заданным идентификатором и заданным именем пользователя из массива в MongoDB в узле

#node.js #mongodb #typescript

#node.js #mongodb #машинописный текст

Вопрос:

У меня есть такая схема, и я хотел бы получить объект user для заданного имени пользователя и _id:

 {
"_id":ObjectId("5cb7267d7ea090083be865c6"),
"name": test,
"users":[
    {
        "userName": "user1",
        "role": "admin"
    },
    {
        "userName": "user2",
        "role": "basic"
    }]
},
{
"_id":ObjectId("5cb7267d7ea090083be865c7"),
"name": test,
"users":[
    {
        "userName": "user3",
        "role": "admin"
    },
    {
        "userName": "user4",
        "role": "basic"
    }]
}
  

Я попробовал следующий запрос, основанный на официальной документации Mongo:

 db.users.find( { _id: new ObjectId(5cb7267d7ea090083be865c6) },
             { users: { $elemMatch: { userName: 'user1' } } } )
  

Я использую typescript и получаю следующее сообщение об ошибке и не уверен, как поступить:

  Argument of type '{ users: { $elemMatch: { userName: string; }; }; }' is not assignable to parameter of type 'FindOneOptions'.
 Object literal may only specify known properties, and 'users' does not exist in type 'FindOneOptions'.
  

Комментарии:

1. find возвращает весь документ. Если вам нужен только один поддокумент users массива, вам нужно использовать docs.mongodb.com/manual/aggregation

2. Это ошибка компиляции typescript, а не ошибка, вызванная самим MongoDB. db.users.find() не похоже на форму драйвера NodeJS, которая была бы больше похожа db.collection('users').find() . Какой драйвер вы на самом деле используете? И откуда взялись определения typescript для этой библиотеки? Потому что я подозреваю, что они неверны или, по крайней мере, несовместимы с используемой библиотекой.

3. Если бы это был драйвер NodeJS, то это действительно должно быть db.collection('users').find({ _id: new ObjectId(5cb7267d7ea090083be865c6) }).project({ users: { $elemMatch: { userName: 'user1' } } }) , если вы просто хотите проекцию соответствующего элемента и, конечно, пустых массивов, где это условие для проекции не соответствует.

Ответ №1:

Я думаю, что вы случайно добавили ненужные фигурные скобки и передали {users: {...}} в качестве аргумента options. Вот почему ваш код не компилируется. Попробуйте это:

 db.users.find( {
 _id: new ObjectId(5cb7267d7ea090083be865c6),
 users: { $elemMatch: { userName: 'user1' } }
});