Использование $match для встроенного документа в агрегате

#javascript #node.js #mongodb #mongoose #backend

#javascript #node.js #mongodb #мангуст #серверная часть

Вопрос:

Я пытаюсь использовать $match для поиска элементов с определенным _id в двойном встроенном документе.

У меня есть документ под названием users, который содержит такую информацию, как имя, адрес электронной почты, а также содержит встроенный документ, в котором указан бизнес, с которым работает этот пользователь.

У меня также есть документ под названием businesses , который содержит встроенный документ, в котором указано здание, в котором находится этот бизнес.

У меня также есть документ под названием building .

Я пытаюсь получить запрос mongo, который возвращает всех пользователей с бизнесом с определенным идентификатором здания.

У меня есть агрегатная функция, которая использует $lookup для сопоставления пользователей со зданием, в котором они находятся. и это действительно работает. Однако теперь я пытаюсь использовать $match, чтобы возвращать документы только с определенным идентификатором здания.

Вот пример моих пользовательских, деловых и строительных документов:

 _id: 5ca487c0eeedbe8ab59d7a7a
name: "John Smith"
email: "jsmith9@gmail.com"
business: Object
  _id: 5ca48481eeedbe8ab59d7a38
  name: "Visitors"


_id: 5ca48481eeedbe8ab59d7a38
name: "Visitors"
building: Object
  _id: 5ca48481eeedbe8ab59d7a36
  name: "Building1"


_id: 5ca48481eeedbe8ab59d7a36
name: "Building1"
  

Когда я возвращаю агрегированный запрос, он возвращает документы в следующем формате:

     {
        "_id": "5ca487c0eeedbe8ab59d7a7a",
        "name": "John Smith",
        "email": "jsmith9@gmail.com",
        "business": {
            "_id": "5ca48481eeedbe8ab59d7a38",
            "name": "Visitors"
        },
        "__v": 0,
        "user_building": {
            "_id": "5ca48481eeedbe8ab59d7a38",
            "name": "Visitors",
            "building": {
                "_id": "5ca48481eeedbe8ab59d7a36",
                "name": "Building1"
            },
            "__v": 0
        }
    },
  

Однако, когда я добавляю совпадение, оно возвращает [] . Что я здесь делаю не так?

 router.get("/:id", async (req, res) => {
  const users_buildings = await User.aggregate([
    {
      $lookup: {
        from: "businesses",
        localField: "business._id",
        foreignField: "_id",
        as: "user_building"
      }
    },
    { $unwind: "$user_building" },

    {
      $match: {
        "user_building.building": { _id: req.params.id }
      }
    }
  ]);
  

Ответ №1:

Вам нужно сопоставить _id внутри объекта построения. Попробуйте с этим

  {
  $match: {
    "user_building.building._id": req.params.id
  }
}
  

если не работает

 {
  $match: {
    "user_building.building._id": ObjectId(req.params.id)
  }
}
  

op edit: я импортировал ObjectId с помощью:

 var ObjectId = require('mongodb').ObjectID;
  

и использовал второе решение, и оно работало правильно.

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

1. Спасибо за ответ, ни один из этих подходов не сработал, и я все равно получил пустой список. Для второго решения ObjectId не был определен, что мне нужно импортировать, чтобы попробовать это.

2. Я использовал «var ObjectId = require(‘mongodb’). ObjectId;» для импорта и повторного запуска запроса, и он сработал. Большое вам спасибо!