Как я могу запросить все документы, которые содержат одно и то же имя пользователя после заполнения в Монго - PullRequest
1 голос
/ 12 марта 2020

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

Пример. если имя пользователя - Мейбл, то возвращать каждый документ, где после заполнения имя пользователя соответствует имени Мейбл

Модель проекта:

{
    "_id": "5e641a033ecd5c172827eba6",
    "title": "My Post",
    "description": "First post",
    "userId": "5e431ba109c629018d664d89",
    "createdAt": "2020-03-07T22:02:43.758Z",
    "__v": 0
}

После заполнения: (модель пользователя, заполненная внутри модели проекта)

{
    "_id": "5e641a033ecd5c172827eba6",
    "title": "My Post",
    "description": "First post",
    "userId": {
        "role": "user",
        "_id": "5e431ba109c629018d664d89",
        "username": "Mabel",
        "createdAt": "2020-02-11T21:24:49.932Z"
    },
    "createdAt": "2020-03-07T22:02:43.758Z",
    "__v": 0
}

Что я пробовал:

const projects = await Projects.find().populate({
    path: "userId",
    match: { username: { $in: username } }
  });

Но в итоге получаю все документы от всех других имен пользователей.

Что мне нужно?

Правильно сейчас у Мейбл три проекта. Эти три проекта принадлежат одному и тому же userId.username. Как я могу запросить все эти документы от этого имени пользователя?

1 Ответ

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

Я предполагаю, что вы пытаетесь получить пользователя с его / ее проектами.

Вы можете легко сделать это с помощью структуры агрегирования.

Сначала мы сопоставляем пользователя с именем пользователя, а затем используем $ lookup агрегация для получения его / ее проектов.

const Users = require("../models/user");   //CHANGE this path according to your user model 
const Projects = require("../models/project");  //CHANGE this path according to your project model 

router.get("/users", async (req, res) => {
  let username = "Mabel";
  const result = await Users.aggregate([
    {
      $match: {
        username: username
      }
    },
    {
      $lookup: {
        from: "projects",  //MUST be the physical name of the collection
        localField: "_id",
        foreignField: "userId",
        as: "projects"
      }
    }
  ]);

  res.send(result);
});

Детская площадка

Образцы документов:

db={
  "users": [
    {
      "_id": "5e6a293637a3d101b488278d",
      "username": "Mabel",
      "role": "user",
      "__v": 0
    },
    {
      "_id": "5e6a294537a3d101b488278e",
      "username": "Tom",
      "role": "user",
      "__v": 0
    },
    {
      "_id": "5e6a294f37a3d101b488278f",
      "username": "Bob",
      "role": "user",
      "__v": 0
    }
  ],
  "projects": [
    {
      "_id": "5e6a298537a3d101b4882790",
      "title": "My Post",
      "description": "First post",
      "userId": "5e6a293637a3d101b488278d",
      "__v": 0
    },
    {
      "_id": "5e6a29a237a3d101b4882791",
      "title": "My Post 2",
      "description": "Second post",
      "userId": "5e6a293637a3d101b488278d",
      "__v": 0
    },
    {
      "_id": "5e6a29bd37a3d101b4882792",
      "title": "Tom post",
      "description": "Tom post description",
      "userId": "5e6a294537a3d101b488278e",
      "__v": 0
    },
    {
      "_id": "5e6a2a0837a3d101b4882793",
      "title": "Bob post",
      "description": "Bob post description",
      "userId": "5e6a294f37a3d101b488278f",
      "__v": 0
    }
  ]
}

Вывод :

[
  {
    "__v": 0,
    "_id": "5e6a293637a3d101b488278d",
    "projects": [
      {
        "__v": 0,
        "_id": "5e6a298537a3d101b4882790",
        "description": "First post",
        "title": "My Post",
        "userId": "5e6a293637a3d101b488278d"
      },
      {
        "__v": 0,
        "_id": "5e6a29a237a3d101b4882791",
        "description": "Second post",
        "title": "My Post 2",
        "userId": "5e6a293637a3d101b488278d"
      }
    ],
    "role": "user",
    "username": "Mabel"
  }
]

Второй вариант :

Если вы хотите использовать заполнение вместо агрегирования, вам нужно настроить виртуальное заполнение . Поскольку у нас нет ссылки на проект внутри пользователя.

Поэтому, чтобы настроить виртуальное заполнение, мы вносим следующие изменения в пользовательскую схему:

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const UserSchema = new Schema(
  {
    username: String,
    role: String
  },
  {
    toJSON: { virtuals: true } //don't forget this option
  }
);

UserSchema.virtual("projects", {
  ref: "Project", // Project here must match mongoose.model("Project", ProjectSchema);
  foreignField: "userId",
  localField: "_id"
});

module.exports = mongoose.model("User", UserSchema);

И теперь мы можем получить пользователя и его / ее проекты как это:

router.get("/users", async (req, res) => {
  let username = "Mabel"; 

  const result = await Users.find({ username }).populate("projects");

  res.send(result);
});
...