mongoose найти поддок с идентификатором CoreMongooseArray vs DocumentArray - PullRequest
0 голосов
/ 02 ноября 2019

У меня есть связь между двумя схемами, для простоты давайте назовем это parent => children.

const ChildScheme = new mongoose.Schema(
    {
        name: { type: String, required: true },
    },
    {
        timestamps:true
    });

const child = mongoose.model("Child", Child);

const ParentScheme = new mongoose.Schema(
    {
        name: { type: String, required: true },
        children: [{type: mongoose.Schema.Types.ObjectId, ref: Child, autopopulate: true}],
    },
    {
        timestamps:true
    });

Теперь я хочу получить конкретного ребенка от конкретного родителя через его идентификатор. .

То, что я пробовал, было:

models.Parent.findById('parent_obj_id')
    .then((parent) => {
        let child = parent.children.id('child_id')
    });

Это, однако, не работает, потомки имеют тип CoreMongooseArray, у которого нет идентификатора функции.

I 'Я немного искал исходный код, и я вижу, что класс CoreDocumentArray, который выходит из CoreMongooseArray, имеет эту функцию.

Почему я получаю CoreMongooseArray? Разве это не работает, потому что на самом деле мангуст

, когда я выполню следующее:

models.Parent.findById('parent_obj_id')
    .then((parent) => {
        console.log(parent);
    });

Я получу этот ответ:

{ children:
   [ { name: [],
       _id: 5dbd9723533e204ab91ccee5,
       name: 'peter',
       createdAt: 2019-11-02T14:48:03.763Z,
       updatedAt: 2019-11-02T14:48:03.763Z,
       __v: 0 } ],
  _id: 5dbd9723533e204ab91ccee3,
  name: 'Walter',
  createdAt: 2019-11-02T14:48:03.596Z,
  updatedAt: 2019-11-02T14:48:03.806Z,
  __v: 3 }

1 Ответ

1 голос
/ 02 ноября 2019

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

models.Parent.findById("parent_obj_id").then(parent => {
  let child = parent.children.find(c => c._id.toString() === "child_id");
  console.log(child);

  //todo: send response
});

Я сделал простую демонстрацию, подобную этой:

(я полагаю, выиспользуя пакет https://www.npmjs.com/package/mongoose-autopopulate для функции автозаполнения)

Родительская модель (команда):

const mongoose = require("mongoose");

const teamSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    unique: true,
    trim: true
  },
  players: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Player",
      autopopulate: true
    }
  ]
});

teamSchema.plugin(require("mongoose-autopopulate"));

const team = mongoose.model("Team", teamSchema);
module.exports = team;

Дочерняя модель: (игрок)

const mongoose = require("mongoose");

const playerSchema = new mongoose.Schema({
  name: String
});

const player = mongoose.model("Player", playerSchema);
module.exports = player;

У меня естьВот такие 3 игрока:

[
    {
        "_id": "5dbdb7cf0101fb08b434a576",
        "name": "player 1",
        "__v": 0
    },
    {
        "_id": "5dbdb7d80101fb08b434a577",
        "name": "player 2",
        "__v": 0
    },
    {
        "_id": "5dbdb7e00101fb08b434a578",
        "name": "player 3",
        "__v": 0
    }
]

У меня есть 1 команда с этими 3 игроками, такими как:

[
    {
        "players": [
            "5dbdb7cf0101fb08b434a576",
            "5dbdb7d80101fb08b434a577",
            "5dbdb7e00101fb08b434a578"
        ],
        "_id": "5dbdb80d0101fb08b434a579",
        "name": "team 1",
        "__v": 0
    }
]

Чтобы получить информацию об игроке 1 команды 1, я использую следующий маршрут:

router.get("/team/:teamId/:playerId", (req, res) => {
  const { teamId, playerId } = req.params;

  Team.findById(teamId).then(team => {
    const player = team.players.find(p => p._id.toString() === playerId);
    res.send(player);
  });
});

И результат:

{
    "_id": "5dbdb7cf0101fb08b434a576",
    "name": "player 1",
    "__v": 0
}
...