Поле виртуального счета mongoose: поле this.populate (). execPopulate () имеет нулевое значение при обращении, если только метод .toJSON () не вызывается в заполненном документе первым - PullRequest
0 голосов
/ 29 декабря 2018

То, что я ожидаю, произойдет:

После заполнения this с populate().execPopulate() через async/await (назначено populatedDoc) или .then(populatedDoc => ):

  • logging this или populatedDoc показывает поле и его правильное значение
  • logging this.fieldName или populatedDoc.fieldName возвращает правильное значение
  • logging this.toJSON().fieldName или populatedDoc.toJSON().fieldName возвращаетправильное значение

Что на самом деле происходит:

После заполнения this с помощью populate().execPopulate() через async/await (назначено populatedDoc) или .then(populatedDoc => ):

  • logging this или populatedDoc показывает поле и его правильное значение
  • logging this.fieldName или populatedDoc.fieldName возвращает null
  • , если я войду в системуthis.toJSON().fieldName или populatedDoc.toJSON().fieldName возвращается правильное значение

Схема (упрощенная)

const storySchema = new mongoose.Schema({
      title: String,
      body: String,
      publishedDate: {
        type: Date,
        default: null,
      },
      published: { // true: published, false: draft
        type: Boolean,
        default: false,
      },
      author: { type: mongoose.SchemaTypes.ObjectId, ref: 'users' },
      parent: { type: mongoose.SchemaTypes.ObjectId, ref: 'stories' },
    }, { timestamps: true });

storySchema.virtual('repliesCount', {
  ref: 'stories', // collection name this field references
  localField: '_id', // the ID to of this story
  foreignField: 'parent', // the field on the Story document to match with the ID
  count: true, // only return a count of documents
});

const Story = mongoose.model('stories', storySchema);

Метод экземпляра

У меня тогда есть метод, в котором я используюполе repliesCount.Я упростил метод в качестве примера.Я пытался использовать как async / await, так и традиционный .then ():

storySchema.methods.test = async function test() {
  this.populate('repliesCount')
    .execPopulate()
    .then((updatedDoc) => {
      console.log(this); // repliesCount field: 1
      console.log(this.repliesCount); // null
      console.log(this.toJSON().repliesCount); // 1

      console.log(updatedDoc); // repliesCount field: 1
      console.log(updatedDoc.repliesCount); // null ??
      console.log(updatedDoc.toJSON().repliesCount); // 1
    });


  const populatedDoc = await this.populate('repliesCount').execPopulate();
  console.log(populatedDoc); // repliesCount field: 1
  console.log(populatedDoc.repliesCount); // null ??
  console.log(populatedDoc.toJSON().repliesCount); // 1
}

Журналы вывода метода экземпляра

console.log models/story.js:146
    { publishedDate: 2018-12-29T00:37:46.267Z,
      published: true,
      _id: 5c26c1da02fb5f2303f071e0,
      author:
       { followers: [],
         following: [],
         _id: 5c26c1da02fb5f2303f071de,
         username: 'linnea',
         avatarURL: 'https://s3.amazonaws.com/uifaces/faces/twitter/yigitpinarbasi/128.jpg',
         createdAt: 2018-12-29T00:37:46.145Z,
         updatedAt: 2018-12-29T00:37:46.145Z,
         __v: 0 },
      title: 'Multi-tiered mobile moratorium',
      body: 'Ut est laborum iure facilis. Voluptate dolores id accusamus. Delectus itaque qui harum occaecati. Consequatur deserunt harum repellendus est ut.\n \rDolorem in nostrum. Quae accusamus tempore eum. Vel sequi ipsam cupiditate excepturi iusto quis. Quam voluptatum aperiam laudantium sit eveniet nisi deserunt cumque. Qui architecto libero aut ipsa quae est saepe ipsam.',
      parent: null,
      createdAt: 2018-12-29T00:37:46.230Z,
      updatedAt: 2018-12-29T00:37:46.268Z,
      __v: 0,
      repliesCount: 1 }

  console.log models/story.js:147
    null

  console.log models/story.js:148
    1
...