найти, существует ли отдельный элемент массива в массиве документа mongodb - PullRequest
4 голосов
/ 12 марта 2020

Есть ли способ узнать, существует ли отдельный элемент в массиве документа mongodb. Например: если у меня есть документ

{
    "_id": "A",
    "userId": "B",
    "selectedUsers": ["C", "D"]
}

, и у меня есть другой массив как ["E", "C"]. Я хочу написать запрос, который выдает результат как [false, true], когда userId и вышеуказанный массив передаются ему, потому что «E» отсутствует в массиве selectedUsers, а «C» находится в массиве selectedUsers.

Я знаю, я могу сначала найти документ с заданным userId, а затем использовать Array.find () для него для отдельного элемента. Но я хочу знать, есть ли способ сделать это в запросе mongodb.

Кроме того, я использую nodeJS и mon goose.

Просто, чтобы было ясно, мне нужно получить та же функциональность, что и в приведенном ниже коде js с использованием запроса mongodb.

// req is the http request
// Selected is the mongoose Model for above document
// usersToCheck = ["E", "C"] (this is the second array)
const result = Selected.findOne({ userId: req.userId});
const { selectedUsers } = result;
const response = usersToCheck.map(uid => {
    if(selectedUsers.some(id => id === uid)){
        return true;
    }
    return false;
})

// response = [false, true]

Теперь приведенный выше код имеет сложность O (n ^ 2), предполагая, что размер usersToCheck и selectedUsers равен n.

Я хочу узнать, как получить тот же ответ, что и выше, используя запрос mongodb. Таким образом, я могу индексировать коллекцию на основе массива selectedUsers и сократить время, необходимое для получения ответа.

Или приветствуется любой другой способ улучшить приведенный выше код.

Спасибо за заранее за вашу помощь.

Ответы [ 3 ]

2 голосов
/ 12 марта 2020

Попробуйте это:

const result = Selected.aggregate([
  {
    $match: {
      userId: req.userId
    }
  },
  {
    $project: {
      _id: 0,
      result: {
        $map: {
          input: ["E", "C"],
          in: {
            $in: [
              "$$this",
              "$selectedUsers"
            ]
          }
        }
      }
    }
  }
]).exec();
const response = result[0].result;

MongoPlayground

1 голос
/ 12 марта 2020

как насчет этого?

var input = ['E', 'C'];

db.collection.aggregate(
    [
        {
            $match: {
                _id: 'A'
            }
        },
        {
            $unwind: '$selectedUsers'
        },
        {
            $set: {
                has: { $in: ['$selectedUsers', input] }
            }
        },
        {
            $group: {
                _id: null,
                result: { $push: '$has' }
            }
        },
        {
            $project: {
                _id: 0
            }
        }
    ])
1 голос
/ 12 марта 2020

Вы можете просто использовать $ в

db.collection.find({selectedUsers: {$in: ["E", "C"]}})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...