带有异步 getter 的 Mongoose 虚拟字段

Mongoose Virtual field with async getter

我有一个项目模型,它是一个虚拟字段来引用库存徽章。

'use strict';

const mongoose = require('mongoose');
const mongooseHidden = require('mongoose-hidden')();
const Badge = mongoose.model('Badge');

const validateProperty = function(property) {
  return (property.length);
};

const Schema = mongoose.Schema;

const ItemSchema = new Schema({
  itemCode: {
    type: Number,
    index: {
      unique: true,
      sparse: true // For this to work on a previously indexed field, the index must be dropped & the application restarted.
    },
    required: true
  },
  itemName: {
    type: String,
    uppercase: true,
    trim: true
  },
  barcode: {
    type: String,
    trim: true
  },
  category: {
    type: Schema.Types.ObjectId,
    ref: 'Category'
  },
  subCategory: {
    type: Schema.Types.ObjectId,
    ref: 'SubCategory'
  },
  updated: {
    type: Date
  },
  created: {
    type: Date,
    default: Date.now
  },
  status: {
    type: String,
    enum: [
      'active', 'inactive', 'removed'
    ],
    default: 'active'
  }
}, {id: false});

ItemSchema.virtual('badges').get(function() {
  return this.getAvailableBadges();
});

ItemSchema.methods.getAvailableBadges = function() {
  Badge.find({
    item: this._id
  }, (err, badges) => {
    if (badges) {
      return badges;
    } else {
      return [];
    }
  });
};

ItemSchema.set('toJSON', {virtuals: true});
ItemSchema.set('toObject', {virtuals: true});

ItemSchema.plugin(mongooseHidden, {
  hidden: {
    _id: false,
    __v: true
  }
});

mongoose.model('Item', ItemSchema);

批处理模型如下

'use strict';

const mongoose = require('mongoose');
const mongooseHidden = require('mongoose-hidden')();

const validateProperty = function(property) {
  return (property.length);
};

const Schema = mongoose.Schema;

const BadgeSchema = new Schema({
  item: {
    type: Schema.Types.ObjectId,
    ref: 'Item'
  },
  qty: {
    type: Number,
    validate: [validateProperty, 'Please enter Quantity !']
  },
  purchasingPrice: {
    type: Number,
    validate: [validateProperty, 'Please enter purchasingPrice !']
  },
  sellingPrice: {
    type: Number,
    validate: [validateProperty, 'Please enter sellingPrice !']
  },
  updated: {
    type: Date
  },
  created: {
    type: Date,
    default: Date.now
  },
  status: {
    type: String,
    enum: [
      'active', 'inactive', 'removed'
    ],
    default: 'active'
  }
});

BadgeSchema.plugin(mongooseHidden, {
  hidden: {
    _id: false,
    __v: true
  }
});

mongoose.model('Badge', BadgeSchema);

项目的徽章虚拟字段未填充。

我们将如何使用异步 getter 方法

我输入了一些控制台日志语句,发现 getAvailableBadges 正在获取数据。

我需要通过快递发送具有虚拟字段值的 json 对象。我该怎么做?

好吧,这些操作是异步的,因此您必须等待回调触发。

您只能通过在回调中传递值来 return 值(或者您可以在调用回调之前设置当前对象的值)。

我想应该是这样的:

ItemSchema.virtual('badges').get(function (callback) {
    Badge.find({ item: this._id }, callback);
};

然后你会像

一样使用它
item.badges(function (err, badges) {
    // do something with badges
});

我所做的是创建一个虚拟 属性

ItemSchema.virtual('badges', {
  ref: 'Badge',
  localField: '_id',
  foreignField: 'item'
});

并用

填充它
{
   path: 'badges',
   select: [
     'qty', 'purchasingPrice', 'sellingPrice'
   ],
   options: {
     sort: {
       'created': -1
     }
   }
}