2016-05-17 9 views
2

MongoDBデータベースによって生成されたObjectIDを短縮する方法を探していますが、私は 'shortid''short-mongo-idのような既存のライブラリのいくつかを認識しています'MongoDB ObjectIdを短くしてMongooseスキーマで使用する方法

しかし、私の問題は、コレクションに存在するすべてのドキュメントのmongooseスキーマに新しい' 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'を試しましたhttps://www.npmjs.com/package/short-mongo-idは、ObjectIdを一意のID文字列の切り捨てバージョンに変換できましたが、スキーマの作成にどのように使用するかはわかりません。 )のvalueOf(とそれを文字列化、this.ObjectIdを使用して、ドキュメントののObjectIdを試してみて、取得するために

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

が、ターミナルは示しています:私が試した

TypeError: Cannot read property 'valueOf' of undefined 

コードのすべてがで行われていますNode.JSと私はNodeJSとMongoDBの両方にとても新しいので、上記のコードでいくつかの重大なエラーが発生している場合は私に修正してください。前もって感謝します!

+0

あなたは[カスタムタイプ](http://mongoosejs.com/docs/customschematypes.html)を実装する必要があります。しかし、一歩前進:なぜあなたは通常の 'ObjectId'を使用できませんか? – robertklep

+0

私は、ユーザーが長いIDを入力する必要があり、URLが非常に乱雑に見えるので、特定のオブジェクトに関する情報のクエリを困難にすると考えました。私は間違っている可能性があります。ObjectIdに基づいたクエリを簡単に実行できる方法があれば教えてください。 –

+0

おそらく、IDを持つユーザーを気にする必要がない方法がありますか?たとえ短くても、どんな形式のIDでも一般的には普通の人が扱うことはできません。 – robertklep

答えて

1

shortidモジュールは、あなたが必要なもののために働く必要があり、あなただけの通常の文字列フィールドとしてshortIdを保存し、(マングーススキーマ定義内で)このように、保存する前に、新しいコードが生成されていることを確認する必要があります。

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を使用しています。一度サーバーが減速する):

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

関連する問題