19

如果我正在构建一个博客,我可以使用博客标题作为唯一标识符并通过 URL 解析它。但是,如果我想使用数字怎么办。你知道 twitter 如何拥有 www.twitter.com/username/statuses/9834542 吗?有没有人想出一个很好的方法来完成这项工作?使用“_id”是不可能的,因为它太长了。

4

5 回答 5

24

只要您可以保证唯一性,您就不会受限于使用默认的“_id”MongoDB 供应品。

因此,如何生成这个数字取决于您。如果您想将此数字存储在 MongoDB 中,那么您可以将其存储在一个单独的集合中,并为每个所需的新 URL 递增它。

增加一个字段是通过使用动词来实现$inc,或者您可能想看看 MongoDB 如何以原子方式更新或增加一个值。

于 2009-09-02T17:13:16.780 回答
17

可以使用findandmodify命令来完成。

假设我们有一个名为的特殊集合sequences,我们希望有一个帖子编号序列(命名postid),您可以使用类似于以下的代码:

> db.runCommand( { "findandmodify" : "序列",
                   “查询”:{“名称”:“postid”},
                   “更新”:{$inc:{“id”:1}},
                   “新”:真});

此命令将自动返回更新的 ( new) 文档以及状态。如果命令成功完成,则该value字段包含返回的文档。

于 2010-10-12T21:52:19.430 回答
7

如果要在 MongoDB 中为自己的字段添加唯一性约束,请使用索引。然后你可以使用任何你想要生成数字的散列算法并测试它的唯一性。MongoDB 文档中的示例是

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

这将阻止您插入与另一个文档具有相同名字和姓氏的文档。

文档中提供了更多信息。

于 2010-05-27T18:01:39.320 回答
4

我通过使用数据创建集合“序列”解决了这个问题:

  • 姓名
  • 当前值

我正在使用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 配置(仅一个节点或主/从或副本集),您必须使用正确的 WriteConcern。在具有一个实例的一个环境中使用 REPLICATION_SAFE 只会导致无限循环。

于 2010-09-25T11:31:02.990 回答
1

从技术上讲,身份证号太大而无法缩短。但是,可以填补一个战术。那是从十六进制传递到字母数字,从而减少了 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。

于 2013-01-14T03:46:30.577 回答