Уникальные идентификаторы с mongodb

Если бы я строил блог, я мог бы использовать заголовок блога как уникальный идентификатор и проанализировать его через URL. Однако, что, если бы я хотел использовать числа. Вы знаете, как твиттер имеет www.twitter.com/username/statuses/9834542? Кто-нибудь придумал хороший способ сделать эту работу? использование "_id" не может быть и речи, поскольку оно слишком длинное.

Ответы

Ответ 1

Пока вы можете гарантировать уникальность, вы не можете использовать по умолчанию "_id" поставки MongoDB.

Таким образом, вам нужно, как вы генерируете это число. Если вы хотите сохранить этот номер внутри MongoDB, вы можете сохранить его в отдельной коллекции и увеличить его для каждого нового URL-адреса.

Приращение поля достигается с помощью $inc verb, или вы можете посмотреть, как MongoDB может атомизировать обновление или увеличивать значение.

Ответ 2

Это можно сделать, используя команду findandmodify.

Давайте рассмотрим, что у нас есть специальный набор с именем sequences, и мы хотим иметь последовательность для почтовых номеров (с именем postid), вы можете использовать код, похожий на этот:

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

Эта команда будет автоматически возвращать обновленный (new) документ вместе со статусом. Поле value содержит возвращенный документ, если команда успешно завершена.

Ответ 3

Если вы хотите добавить ограничение уникальности в свое поле в MongoDB, используйте индекс. Затем вы можете использовать любой алгоритм хеширования, который вы хотите сгенерировать, и проверить его на уникальность. Пример в документации MongoDB:

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

что помешает вам вставить документы с таким же именем и фамилией в качестве другого документа.

Дополнительная информация доступна в документации.

Ответ 4

Я решил эту проблему, создав "последовательность" коллекции с данными:

  • имя
  • значение currurt

Я использую Morhpia, так что для этого DAO. Но вы можете сделать это и без Морхпии. Идея заключается в использовании $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 (только один node или мастер/ведомый или набор реплик) вы должны использовать правильный WriteConcern. Использование REPLICATION_SAFE в одной среде с одним экземпляром вызывает только бесконечный цикл.

Ответ 5

Технически, идентификационный номер слишком велик, чтобы сократить его. Однако тактика может быть заполнена. Это переход от Hex к буквенно-цифровому, что уменьшает количество символов до 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!!!

Конечно, этот метод использует тот же идентификатор, mongo.