2009-08-29 16 views
15

के साथ अद्वितीय आईडी यदि मैं एक ब्लॉग बना रहा था तो मैं ब्लॉग शीर्षक का अद्वितीय पहचानकर्ता के रूप में उपयोग कर सकता हूं और इसे यूआरएल के माध्यम से पार्स कर सकता हूं। हालांकि, अगर मैं संख्याओं का उपयोग करना चाहता था तो क्या होगा। आप जानते हैं कि ट्विटर के पास www.twitter.com/username/statuses/9834542 कैसे है? क्या किसी ने इस काम को करने का एक अच्छा तरीका निकाला है? "_id" का उपयोग प्रश्न से बाहर है क्योंकि यह बहुत लंबा है।mongodb

+0

आप यूआरएल का एमडी 5 (या कोई भी) हैश कर सकते हैं और इसे _id के स्थान पर स्टोर कर सकते हैं। –

उत्तर

22

जब तक आप विशिष्टता की गारंटी दे सकते हैं, तो आप डिफ़ॉल्ट "_id" MongoDB आपूर्ति का उपयोग करने के लिए बाध्य नहीं हैं।

इसलिए, यह आपके लिए नीचे है कि आप इस नंबर को कैसे उत्पन्न करते हैं। यदि आप इस नंबर को मोंगोडीबी के अंदर स्टोर करना चाहते हैं, तो आप इसे एक अलग संग्रह में स्टोर कर सकते हैं और आवश्यक प्रत्येक नए यूआरएल के लिए इसे बढ़ा सकते हैं।

the $inc verb का उपयोग करके एक क्षेत्र में वृद्धि हासिल की जाती है, या आप यह देखने के लिए चाहते हैं कि कैसे MongoDB atomically update या मूल्य बढ़ा सकता है।

+0

एलन ने कहा, आप अपनी आईडी प्रदान कर सकते हैं। तो सवाल यह है कि आप इसे विशिष्ट रूप से कैसे उत्पन्न कर सकते हैं। सबसे आसान यह है कि यदि आपके पास कुछ अनुक्रम सर्वर था (यानी कुछ जो एक संख्या को बाहर निकालता है और फिर वृद्धि करता है, तो लॉक धारण करता है, इसलिए यह परमाणु रूप से होता है। यह अनुक्रम सर्वर प्रति अनुक्रम –

7

यदि आप MongoDB में अपने क्षेत्र में एक विशिष्टता बाधा जोड़ना चाहते हैं, तो एक अनुक्रमणिका का उपयोग करें। फिर आप किसी भी हैशिंग एल्गोरिदम का उपयोग कर सकते हैं जिसे आप संख्या उत्पन्न करना चाहते हैं और विशिष्टता के लिए इसका परीक्षण करना चाहते हैं। MongoDB दस्तावेज में उदाहरण

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

जिसकी सहायता से आप firstname और किसी अन्य दस्तावेज़ के रूप में उपनाम के साथ दस्तावेजों डालने से रोकने जाएगा।

अधिक जानकारी documentation में उपलब्ध है।

4

मैं डेटा के साथ संग्रह 'अनुक्रम' बनाने के द्वारा इस समस्या का समाधान कर दिया है:

  • नाम
  • currurt मूल्य

मैं Morhpia उपयोग कर रहा हूँ, इसलिए यह डीएओ की है। लेकिन आप मोरपिया के बिना भी ऐसा कर सकते हैं। आइडिया $ परमाणु का उपयोग करना है (शायद इसे केवल 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 का उपयोग केवल अनंत लूप का कारण बनता है।

+0

का एक एकल मोंगो रिकॉर्ड का उपयोग कर सकता है यह कौन सा भाषा है? :) आंख! – asyncwait

15

यह findandmodify कमांड का उपयोग करके किया जा सकता है।

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

यह आदेश atomically अद्यतन वापस आ जाएगी:

के पर विचार हम एक विशेष संग्रह sequences नामित है, तो आप इस के समान कोड का इस्तेमाल कर सकते हैं और हमने पोस्ट की संख्या (postid नाम) के लिए एक दृश्य करना चाहते हैं (new) स्थिति के साथ एक साथ दस्तावेज। कमांड सफलतापूर्वक पूरा होने पर value फ़ील्ड में लौटा हुआ दस्तावेज़ शामिल है।

+0

आप इस काम को एक शापित वातावरण में कैसे बनाते हैं? – BlitzKrieg

+0

@blitzKrieg, दस्तावेज़ीकरण के अनुसार: "* findandmodify * एक mongos के माध्यम से बुलाए जाने पर वही व्यवहार करेगा जब तक कि यह संग्रह संशोधित नहीं हो रहा है। अगर संग्रह sharded है, तो क्वेरी में shard कुंजी होना चाहिए।" तो, बस 'अनुक्रम' संग्रह को दाढ़ी न दें? –

+0

इसे @ हबर्ट मिला ... धन्यवाद !! – BlitzKrieg

1

तकनीकी रूप से, आईडी संख्या इसे छोटा करने के लिए बहुत बड़ी है।हालांकि, एक रणनीति भरी जा सकती है। वह हेक्स से अल्फान्यूमेरिक तक गुज़र रहा है, इस प्रकार ट्यूलिज़र के पात्रों की संख्या को कम करता है और यूआरएल में और अधिक सुंदर दिखता है। मैंने वास्तव में बहुत अच्छी तरह से सेवा की ... यहां

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

बेशक यह तकनीक एक ही आईडी, मोंगो का उपयोग करती है।