ブログを作成している場合は、ブログのタイトルを一意の識別子として使用し、URLを介して解析できます。ただし、数字を使用したい場合はどうなりますか。 Twitterがwww.Twitter.com/username/statuses/9834542をどのように持っているか知っていますか?誰かがこの作品を作るための素晴らしい方法を考え出しましたか? 「_id」の使用は長すぎるため、問題外です。
findandmodify コマンドを使用して実行できます。
sequences
という名前の特別なコレクションがあり、投稿番号(postid
という名前)のシーケンスが必要な場合は、次のようなコードを使用できます。
> db.runCommand({"findandmodify": "sequences"、 "query":{"name": "postid"}、 "update":{$ inc :{"id":1}}、 "new":true});
このコマンドは、更新された(new
)ドキュメントをステータスとともにアトミックに返します。 value
フィールドには、コマンドが正常に完了した場合に返されるドキュメントが含まれます。
MongoDBの独自のフィールドに一意性制約を追加する場合は、インデックスを使用します。次に、番号を生成する任意のハッシュアルゴリズムを使用して、一意性をテストできます。 MongoDBドキュメントの例は次のとおりです。
db.things.ensureIndex({firstname: 1, lastname: 1}, {unique: true});
これにより、別のドキュメントと同じ名と姓のドキュメントを挿入できなくなります。
詳細については、 ドキュメント を参照してください。
データを使用してコレクション「シーケンス」を作成することで、この問題を解決しました。
Morhpia を使用しているので、DAOを使用します。しかし、Morhpiaなしでもそれを行うことができます。アイデアは、$ atomic(おそらく、1つのインスタンスのみを更新するために省略できます)と $ inc 修飾子演算子を使用することです。
シーケンス
@Entity(value = "sys_sequence", noClassnameStored = true)
public class SequenceM {
/**
* Names of entity
*/
public static enum Entity {
USER,
CAPABILITY_HISTORY;
public String getEntityName() {
return this.name().toLowerCase();
}
}
@Id
private ObjectId uid;
@Property
@Indexed(unique = true)
private String name;
@Property
private Long value;
//..getters/setters/etc
}
SequenceDAOのメソッド:
@NotNull
public Long nextValue(final @NotNull SequenceM.Entity entity) {
final DB db = this.ds.getDB();
final WriteConcern writeConcern = getWriteConcern();
//optimization for JVM instance
synchronized(entity) {
do {
SequenceM sequence = findOne("name", entity.getEntityName());
final DBObject q = BasicDBObjectBuilder.start().add("name", entity.getEntityName()).add("value", sequence.getValue()).add("$atomic", 1).get();
final DBObject o = BasicDBObjectBuilder.start().add("$inc", BasicDBObjectBuilder.start().add("value", 1).get()).get();
WriteResult writeResult = db.getCollection("sys_sequence").update(q, o, false, true, writeConcern);
if(writeResult.getN() == 1) {
return sequence.getValue() + 1;
}
} while(true);
}
}
/**
* Determining writing concern basing on configuration
*/
private WriteConcern getWriteConcern() {
return isOneNodeOnly ? WriteConcern.SAFE : REPLICATION_SAFE;
}
MongoDB構成(1つのノードのみ、またはマスター/スレーブまたはレプリカセット)に応じて、正しいWriteConcernを使用する必要があります。 1つのインスタンスを持つ1つの環境でREPLICATION_SAFEを使用すると、無限ループが発生するだけです。
技術的には、ID番号が大きすぎて短縮できません。ただし、戦術は満たすことができます。これは16進数から英数字に移行しているため、文字数がtulizarに減り、URLでより美しく見えます。私は本当にとてもよく仕えました...ここにあります
function encode(hex) {
return new Buffer(hex, 'hex').toString('base64').replace('+', '-').replace('/', '_');
};
function decode(NoHex) {
return new Buffer( NoHex.replace('-','+').replace('_','/'), 'base64').toString('hex');
};
IdString= MyDoc._id.toString();
Idencode = encode( IdString ) // 16 Caracters a-Z and 0-9
console.log( IdEncode ); //You see That 'aqswedasdfdsadsf'
IdDecode = decode( IdEncode );
IdDecode === IdString // Is true!!!
もちろん、この手法では同じID、mongoを使用します。