如何缩短MongoDB的ObjectId并在Mongoose模式中使用它

我正在寻找一种方法来缩短由MongoDB数据库生成的ObjectID,我知道一些现有的库,如'shortid''short-mongo-id'

但是,我的问题是,我希望在集合中存在的每个文档的mongoose模式中创build一个新的“shortID”字段,这个新的字段应该是唯一的,理想情况下是连接到文档的ObjectId的截断版本。 像这样:

var subjectSchema = new Schema({ shortID: {required: true, unique: true}, //must be unique to each document and is same everytime server restarts Sex: {type: String, enum: enumSex}, Diagnosis: String, Projects:[projectPerSubjectSchema] }); 

“shortid” https://www.npmjs.com/package/shortid库工作良好,并生成唯一的ID,但是,每次服务器重新启动时,它会生成不同的ID,这不是我想要的。

另一个我试过'short-mongo-id'的库能够把ObjectId转换成唯一IDstring的截断版本,但是,我不知道如何用它来创build一个模式。 我试过了:

 ID: {type: String, 'default': shortid((this.ObjectId).valueOf()), unique: true} 

尝试使用this.ObjectId获取文档的ObjectId,使用valueOf()对其进行string化,但terminal显示:

 TypeError: Cannot read property 'valueOf' of undefined 

所有的代码都在Node.JS中完成,我对NodeJS和MongoDB都很新,所以如果我在上面提供的代码中犯了一些重大错误,请纠正我的错误。 提前致谢!

shortid模块应该可以满足你需要,你只需要将shortId保存为普通的String字段,并确保在保存之前生成一个新的代码,就像这样(在mongoose模式定义中):

 const mongoose = require('mongoose') const shortid = require('shortid') const Schema = mongoose.Schema const schema = new Schema({ _shortId: { type: String, unique: true }, ... // other fields... }) // This is for checking if the document already have a _shortId, // so you don't replace it with a new code schema.pre('save', function (next) { let doc = this if (!this._shortId) { addShortId(doc, next) } }) function addShortId (doc, next) { let newShortId = shortid.generate() doc.constructor.findOne({_shortId: newShortId}).then((docRes) => { if (docRes) { addShortId(doc, next) } else { doc._shortId = newCode next() } }, (err) => { next(err) }) } 

如果你想为所有现有的文档插入_showId,你只需要一个forEach并再次保存模型,这就是我正在做的(使用https://github.com/JMPerez/promise-throttle ,因为它是一个巨大的收集,一次调用save()将放慢服务器):

 XXXXX.find({ '_shortId': { '$exists': false } }).then((data) => { var promiseThrottle = new PromiseThrottle({ requestsPerSecond: 50, promiseImplementation: Promise }) var i = 1 data.forEach(element => { var myFunction = function (j) { return element.save() } promiseThrottle.add(myFunction.bind(this, i++)).then(ss => { console.log('done ' + ss._shortId) }) }) 

其中一些代码是从https://github.com/dylang/shortid/issues/65改编的