Unique IDs with mongodb

偶尔善良 提交于 2019-11-27 11:58:50
Alan

As long as you can guarantee uniqueness, you're not constrained to using the default "_id" MongoDB supplies.

Therefore, it's down to you how you generate this number. If you'd like to store this number inside MongoDB, then you could store it in a separate collection and increment it for every new URL required.

Incrementing a field is achieved by using the $inc verb, or you may want to take a look at how MongoDB can atomically update or increment a value.

It can be done by using the findandmodify command.

Let's consider we have a special collection named sequences and we want to have a sequence for post numbers (named postid), you could use code similar to this:

> db.runCommand( { "findandmodify" : "sequences",
                   "query" : { "name" : "postid"},
                   "update" : { $inc : { "id" : 1 }},
                   "new" : true } );

This command will return atomically the updated (new) document together with status. The value field contains the returned document if the command completed successfully.

If you want to add a uniqueness constraint to your own field in MongoDB, use an index. Then you can use any hashing algorithm you want to generate the number and test it for uniqueness. The example in the MongoDB documentation is

db.things.ensureIndex({firstname: 1, lastname: 1}, {unique: true});

which will prevent you from inserting documents with the same firstname AND lastname as another document.

More information is available in the documentation.

vmorarian

I have solved this problem by creating collection 'sequence' with data:

  • name
  • currurt value

I'm using Morhpia, so have DAO for it. But you can do it without Morhpia too. Idea is to use $atomic (probably it can be omitted due updateing 1 instance only) and $inc modifier operator.

Sequence

@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
 }

Method on 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;
}

Depending on MongoDB configuration (one node only or master/slave or replica set) you have to use correct WriteConcern. Using REPLICATION_SAFE in one environment with one instance only causes infinite loop.

Technically, the ID number is too large to shorten it. However, a tactic can be filled. That is passing from Hex to alphanumeric, thus reducing the number of characters to tulizar and looks more beautiful in the Url. I really served very well ... here is

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!!!

Of course this technique uses the same id, mongo.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!