प्रमुख नाम में MongoDB डॉट;)


94

ऐसा लगता है कि मोंगो एक डॉट (।) या डॉलर चिन्ह ($) के साथ चाबियों को सम्मिलित करने की अनुमति नहीं देता है, लेकिन जब मैंने एक JSON फ़ाइल आयात की, जिसमें mongoimport उपकरण का उपयोग करके इसमें एक डॉट शामिल था जो ठीक काम करता था। ड्राइवर उस तत्व को डालने की कोशिश कर रहा है।

डेटाबेस में दस्तावेज़ ऐसा दिखता है:

{
    "_id": {
        "$oid": "..."
    },
    "make": "saab",
    "models": {
        "9.7x": [
            2007,
            2008,
            2009,
            2010
        ]
    }
}

क्या मैं यह सब गलत कर रहा हूं और बाहरी डेटा (यानी मॉडल) के साथ हैश मैप का उपयोग नहीं करना चाहिए या क्या मैं किसी तरह डॉट से बच सकता हूं? शायद मैं बहुत ज्यादा जावास्क्रिप्ट की तरह सोच रहा हूँ।


वर्थ, को देख npmjs.com/package/mongo-escape
सैम Denty

जवाबों:


85

MongoDB उनमें एक डॉट के साथ कुंजियों का समर्थन नहीं करता है, इसलिए आपको इसे आयात करने से पहले हटाने या बदलने के लिए अपनी JSON फाइल को प्रीप्रोसेस करना होगा या आप सभी प्रकार की समस्याओं के लिए खुद को स्थापित करेंगे।

इस समस्या के लिए कोई मानक समाधान नहीं है, सबसे अच्छा तरीका स्थिति की बारीकियों पर भी निर्भर है। लेकिन मैं किसी भी प्रमुख एनकोडर / डिकोडर दृष्टिकोण से बचना चाहूंगा यदि संभव हो तो आप उस निरंतरता की असुविधा का भुगतान करना जारी रखेंगे, जहां एक JSON पुनर्गठन निश्चित रूप से एक बार की लागत होगी।


1
मुझे नहीं लगता कि कोई मानक तरीका है, सबसे अच्छा तरीका भी स्थिति की बारीकियों पर निर्भर है। लेकिन मैं किसी भी प्रमुख एनकोडर / डिकोडर दृष्टिकोण से बचना होगा यदि संभव हो तो आप उस निरंतरता की असुविधा का भुगतान करना जारी रखेंगे, जहां एक JSON पुनर्गठन संभवतः एक बार की लागत होगी।
जॉनीएचके

8
इस स्थिति में फिर से भाग गया। ऐसा लगता है कि ऐप के प्रमुख नामों के साथ ऐसा नहीं है, जिसे हम नियंत्रित कर सकते हैं और अक्सर इस पर क्वेरी करने की आवश्यकता होती है, लेकिन उपयोगकर्ता को नेस्टेड डेटा संरचनाओं में डेटा की आपूर्ति की जाती है, जिसे हम नियंत्रित नहीं कर सकते, लेकिन (ए) मोंगो में स्टोर करना चाहते हैं , (बी) हम जानते हैं कि यह कौन से विशिष्ट क्षेत्रों में हो सकता है (जैसे modelsयहां), और (ग) हम नहीं चाहते हैं, उन्हें मानगो में प्रमुख नाम से क्वेरी की आवश्यकता है। तो एक पैटर्न जो मैंने बसाया है वह JSON.stringifyइस फील्ड में सेव पर है, और 'JSON.parse` को पुनः प्राप्त करना है।
प्रोटोटाइप

16
यदि आपको आवश्यक है, तो आप इस समस्या को बायपास करने के लिए {check_keys: false} विकल्प प्रदान कर सकते हैं।
टज़री बार योचाय

5
@TzuryBarYochay OMG आपको उत्तर-पश्चिम मार्ग के बराबर MongoDB मिला है। मुझे लगता है कि यह स्वीकृत उत्तर होना चाहिए।
प्रोटोटाइप

2
@emarel db.collection_foo.update ({यह: "यह"}, {$ सेट: {a: "b"}}, {check_keys: false})
टज़ीरी बार योचाय

22

के रूप में अन्य उत्तर में बताया गया MongoDB की अनुमति नहीं है $या .की वजह से नक्शा कुंजी के रूप में वर्ण फ़ील्ड नामों पर प्रतिबंध । हालांकि, जैसा कि डॉलर साइन ऑपरेटर में उल्लेख किया गया है, इस प्रतिबंध से बचना आपको ऐसी चाबियों के साथ दस्तावेज़ सम्मिलित करने से नहीं रोकता है, यह आपको उन्हें अपडेट करने या क्वेरी करने से रोकता है।

बस की जगह की समस्या .के साथ [dot]या U+FF0E(के रूप में इस पृष्ठ पर कहीं उल्लेख) क्या जब उपयोगकर्ता वैध कुंजी संग्रहीत करना चाहता है होता है, है [dot]या U+FF0E?

एक दृष्टिकोण जो फेंटम के एफ़ोर्फिया चालक को लगता है, वह जावा के समान यूनिकोड एस्केप अनुक्रम का उपयोग करना है, लेकिन भागने के चरित्र को सुनिश्चित करना पहले बच जाता है। संक्षेप में, निम्नलिखित स्ट्रिंग प्रतिस्थापन किए गए हैं (*):

\  -->  \\
$  -->  \u0024
.  -->  \u002e

एक रिवर्स रिप्लेसमेंट तब किया जाता है जब मैप कीज को बाद में MongoDB से पढ़ा जाता है

या फेंटम कोड में:

Str encodeKey(Str key) {
    return key.replace("\\", "\\\\").replace("\$", "\\u0024").replace(".", "\\u002e")
}

Str decodeKey(Str key) {
    return key.replace("\\u002e", ".").replace("\\u0024", "\$").replace("\\\\", "\\")
}

किसी उपयोगकर्ता को इस तरह के रूपांतरणों के बारे में जानने के लिए केवल समय की आवश्यकता होती है जब वह ऐसी चाबियों के लिए क्वेरीज़ का निर्माण करता है।

यह देखते हुए कि dotted.property.namesकॉन्फ़िगरेशन उद्देश्यों के लिए डेटाबेस में संग्रहीत करना आम है, मेरा मानना ​​है कि इस दृष्टिकोण को ऐसे सभी मानचित्र कुंजियों पर प्रतिबंध लगाने के लिए बेहतर है।

(*) afMorphia वास्तव में जावा में यूनिकोड एस्केप सिंटैक्स में उल्लिखित पूर्ण / उचित यूनिकोड भागने के नियम करता है, लेकिन वर्णित प्रतिस्थापन अनुक्रम ठीक वैसे ही काम करता है।


//gसभी घटनाओं को बदलने के लिए उपयोग करना चाहिए और न केवल पहले। मार्टिन कोंसेनी के उत्तर में पूर्ण-चौड़ाई वाले समकक्षों का उपयोग करना एक अच्छा विचार है। अंत में, एक बैकस्लैश एन्कोडिंग के लिए पर्याप्त है। key.replace(/\./g, '\uff0e').replace(/\$/g, '\uff04').replace(/\\/g, '\uff3c')
cw '

1
@cw '- कोड सिंटैक्स की तरह जावा में है, इसलिए वास्तव में सभी घटनाओं को प्रतिस्थापित करता है, और बैकस्लैश से बचने के लिए डबल बैकस्लैश की आवश्यकता होती है। और फिर, आपको सभी मामलों को कवर करने के लिए भागने के कुछ फार्म को पेश करने की आवश्यकता है । किसी को, किसी समय, वास्तव में एक कुंजी की आवश्यकता हो सकती है U+FF04
स्टीव एयॉन

2
जैसा कि यह पता चला है, मोंगोडब नवीनतम संस्करणों में डॉट्स और डॉलर का समर्थन करता है। देखें: - stackoverflow.com/a/57106679/3515086
अभिमान

18

मोंगो डॉक्स जैसे अवैध अक्षर की जगह का सुझाव देते हैं $और .उनके यूनिकोड समकक्ष के साथ।

इन स्थितियों में, आरक्षितों को आरक्षित $ को स्थानापन्न करने की आवश्यकता होगी। पात्र। कोई भी वर्ण पर्याप्त है, लेकिन यूनिकोड पूर्ण चौड़ाई समतुल्य का उपयोग करने पर विचार करें: U + FF04 (अर्थात "U") और U + FF0E (अर्थात "।")।


74
यह सड़क पर बड़े पैमाने पर डिबगिंग सिरदर्द के लिए एक नुस्खा की तरह लगता है।
कोई भी

2
@AndrewMedico, @tamlyn - मुझे लगता है कि डॉक्स का मतलब कुछ ऐसा हैdb.test.insert({"field\uff0ename": "test"})
P. Myer Nore

4
-1 ए यह एक भयानक विचार है - क्या होगा अगर कोई वास्तव में उन यूनिकोड वर्णों को एक कुंजी के रूप में उपयोग करने की कोशिश कर रहा है? फिर आपके पास एक मौन त्रुटि है जो यह करेगी कि आपके सिस्टम को कौन जानता है। उस तरह अस्पष्ट बचने के तरीकों का उपयोग न करें। B. मोंगो डॉक्स अब ऐसा नहीं कहते हैं, शायद इसलिए कि किसी को इसके भयानक विचार का एहसास हुआ
बीटी

7
@SergioTulentsev मैं उन्हें सिफारिश निकालने के लिए मिला:) github.com/mongodb/docs/commit/…
BT

2
@ बीटी: हैट टिप टू यू, सर :)
सर्जियो तुलेंत्सेव

15

MongoDB का नवीनतम स्थिर संस्करण (v3.6.1) अब कुंजियों या फ़ील्ड नामों में डॉट्स (।) का समर्थन करता है।

फ़ील्ड नामों में अब डॉट्स (?) और डॉलर ($) अक्षर हो सकते हैं


10
यहां तक ​​कि अगर सर्वर अब इसका समर्थन करता है, तो ड्राइवर अभी भी कुंजी में $ और डॉट्स के लिए जांच करता है और उन्हें स्वीकार नहीं करता है। इसलिए मानगो केवल सैद्धांतिक रूप से डॉट्स और डॉलर वर्णों का समर्थन करता है। व्यावहारिक रूप से यह अभी भी प्रयोग करने योग्य नहीं है :(
JMax

शायद आप किसी पुराने या असंगत ग्राहक का उपयोग कर रहे हैं। मैं अपने उत्पादन सर्वर पर बिना किसी पसीने के इसका उपयोग कर रहा हूं। मैंने NodeJS और Java क्लाइंट के लिए जाँच की है।
h4ck3d

जावा के साथ यह निश्चित रूप से काम नहीं करता है! निम्न आदेश का प्रयास करें: mongoClient.getDatabase("mydb").getCollection("test").insertOne(new Document("value", new Document("key.with.dots", "value").append("$dollar", "value")));यह mongodb-driver.3.6.3 और MongoDB 3.6.3 का उपयोग करने में विफल रहता है।
JMax

1
वास्तव में, मैंने बस एक सेटअप के साथ प्रयास किया mongodb-4.1.1और pymongo-3.7.1। मैं .डकैतों के साथ चाबियों वाले दस्तावेज़ों को जोड़ सकता हूं pymongo, लेकिन इससे नहीं , यह बढ़ा देता है InvalidDocument: key '1.1' must not contain '.'काश अब तक यह तय हो गया होता ...
लर्निंग एक गड़बड़ है

मैंने mongodb सर्वर 4.0.9 और जावा ड्राइवर 3.10.2 के साथ कोशिश की, लेकिन यह प्रमुख नाम में डॉट को स्वीकार नहीं करता है। यह अजीब है कि जब कोशिश करें कि रोबोमोंगो का उपयोग करें तो यह काम करता है ...
xyzt

12

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

{
    ...
    keyName: "domain.com",
    keyValue: "unregistered",
    ...
}

आप अभी भी इस आसान पर्याप्त क्वेरी कर सकता है, बस एक करके findखेतों पर keyName और keyValue

इसलिए इसके बजाय:

 db.collection.find({"domain.com":"unregistered"})

जो वास्तव में उम्मीद के मुताबिक काम नहीं करेगा, आप दौड़ेंगे:

db.collection.find({keyName:"domain.com", keyValue:"unregistered"})

और यह अपेक्षित दस्तावेज वापस कर देगा।


अपने यह कैसे किया? क्या आप कृपया मुझे उसी मामले में मदद कर सकते हैं।
प्रोफाइलर

मैंने एक क्वेरी उदाहरण जोड़ा। क्या उससे मदद हुई?
स्टीव

10

आप मान के बजाय कुंजी में हैश का उपयोग करने का प्रयास कर सकते हैं, और फिर उस मान को JSON मान में संग्रहीत कर सकते हैं।

var crypto = require("crypto");   

function md5(value) {
    return crypto.createHash('md5').update( String(value) ).digest('hex');
}

var data = {
    "_id": {
        "$oid": "..."
    },
    "make": "saab",
    "models": {}
}

var version = "9.7x";

data.models[ md5(version) ] = {
    "version": version,
    "years" : [
        2007,
        2008,
        2009,
        2010
    ]
}

आप बाद में हैश का उपयोग करके मॉडलों तक पहुंचेंगे।

var version = "9.7x";
collection.find( { _id : ...}, function(e, data ) {
    var models = data.models[ md5(version) ];
}

1
मुझे यह पसंद है, 1-वे हैशिंग के साथ स्वच्छ समाधान और वास्तव में हुड के नीचे काम करने के तरीके के समान।
माइकल यागुडेव

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

2
एक विशेष चरित्र या अनुक्रम के साथ अवधि को बदलने की तुलना में यह बेहतर क्यों है?
बी सेवन

स्ट्रिंग्स को बेस 64 में परिवर्तित करना ज्यादा बेहतर है।
झेन

8

यह अब समर्थित है

MongoDb 3.6 बाद में क्षेत्र के नाम में डॉट्स और डॉलर दोनों का समर्थन करता है । नीचे देखें JIRA: https://jira.mongodb.org/browse/JAVA-2810

अपने मोंगोडेब को 3.6+ में अपग्रेड करना सबसे अच्छा तरीका है।


यह यहाँ सबसे अच्छा जवाब है। : +1
हैलो_अभिषेक

3
3.6 उन्हें स्टोर कर सकते हैं, हां, लेकिन यह अभी तक समर्थित नहीं है, ड्राइवर त्रुटियों को फेंक सकता है, और क्वेरी / अपडेट को तोड़ सकता है: प्रतिबंध : "MongoDB क्वेरी भाषा हमेशा उन दस्तावेज़ों पर प्रश्नों को सार्थक रूप से व्यक्त नहीं कर सकती जिनके क्षेत्र के नाम में ये वर्ण हैं (देखें SERVER- 30575)। जब तक समर्थन को क्वेरी भाषा में नहीं जोड़ा जाता है, तब तक और फ़ील्ड नामों में $ और का उपयोग अनुशंसित नहीं है और आधिकारिक MongoDB ड्राइवरों द्वारा समर्थित नहीं है । "
जेरेमीडाऊल जूल

4

से MongoDB डॉक्स " '।' मुख्य नाम में वर्ण कहीं भी दिखाई नहीं देना चाहिए "। ऐसा लगता है कि आपको एक एन्कोडिंग योजना के साथ आना होगा या इसके बिना करना होगा।


4

आपको कुंजियों से बचना होगा। चूंकि ऐसा लगता है कि ज्यादातर लोगों को यह नहीं पता है कि तारों को ठीक से कैसे बचाना है, यहाँ कदम हैं:

  1. एक भागने चरित्र चुनें (एक चरित्र का चयन करने के लिए सबसे अच्छा है जो शायद ही कभी उपयोग किया जाता है)। उदाहरण के लिए। '~'
  2. भागने के लिए, पहले भागने के चरित्र के सभी उदाहरणों को अपने भागने वाले चरित्र (जैसे '~ ~ ->' ~ t ') के साथ पहले से छोड़ दें, फिर जो भी चरित्र या क्रम आपको भागने के लिए आवश्यक है, उसे अपने भागने वाले चरित्र के साथ पहले से बदल दें । उदाहरण के लिए। '।' -> '~ p'
  3. अनस्केप करने के लिए, पहले अपने दूसरे एस्केप सीक्वेंस के सभी उदाहरणों (जैसे '~ p' -> '') से एस्केप सीक्वेंस को हटा दें, फिर अपने एस्केप कैरेक्टर सीक्वेंस को सिंगल एस्केप कैरेक्टर में बदलें (जैसे '~ s' -> '~ ')

यह भी याद रखें कि मोंगो भी कुंजी को '$' से शुरू नहीं होने देता है, इसलिए आपको वहां भी कुछ ऐसा ही करना होगा

यहाँ कुछ कोड है जो यह करता है:

// returns an escaped mongo key
exports.escape = function(key) {
  return key.replace(/~/g, '~s')
            .replace(/\./g, '~p')
            .replace(/^\$/g, '~d')
}

// returns an unescaped mongo key
exports.unescape = function(escapedKey) {
  return escapedKey.replace(/^~d/g, '$')
                   .replace(/~p/g, '.')
                   .replace(/~s/g, '~')
}

यह पलायन अभी भी टूट सकता है, अगर आपको '~। ~' जैसे तार मिले। यहां बची हुई स्ट्रिंग '~ p ~~ p ~ p' होगी। अनसॉर्सिंग आपको '~। ~' देगा, जो वास्तविक स्ट्रिंग से अलग है।
jvc

1
@jvc तुम सही हो! मैंने स्पष्टीकरण और उदाहरण से बचने के कार्यों को निर्धारित किया है। मुझे पता है अगर वे अभी भी टूट रहे हैं!
BT

3

एक देर से जवाब, लेकिन अगर आप स्प्रिंग और मोंगो का उपयोग करते हैं, तो स्प्रिंग आपके साथ रूपांतरण का प्रबंधन कर सकता है MappingMongoConverter। यह जॉनीएचके द्वारा समाधान है लेकिन वसंत द्वारा नियंत्रित किया जाता है।

@Autowired
private MappingMongoConverter converter;

@PostConstruct
public void configureMongo() {
 converter.setMapKeyDotReplacement("xxx");
}

यदि आपका संग्रहित Json है:

{ "axxxb" : "value" }

स्प्रिंग (MongoClient) के माध्यम से इसे इस प्रकार पढ़ा जाएगा:

{ "a.b" : "value" }

आवश्यक प्रकार के 'सेम। org.springframework.data.mongodb.core.convert.MappingMongoConverter' की एक बीन की आवश्यकता नहीं है।
सत्य नारायण C

1

मैं प्रत्येक ऑब्जेक्ट कुंजी के लिए जावास्क्रिप्ट में निम्नलिखित भागने का उपयोग करता हूं:

key.replace(/\\/g, '\\\\').replace(/^\$/, '\\$').replace(/\./g, '\\_')

मुझे जो पसंद है वह यह है कि यह केवल $शुरुआत में बदल देता है , और इसमें यूनिकोड वर्ण का उपयोग नहीं किया जाता है जो कंसोल में उपयोग करने के लिए मुश्किल हो सकता है। _मेरे लिए एक यूनिकोड चरित्र की तुलना में बहुत अधिक पठनीय है। यह विशेष वर्णों ( $, .) के एक सेट को दूसरे (यूनिकोड) से प्रतिस्थापित नहीं करता है । लेकिन ठीक से पारंपरिक के साथ भाग जाता है \


3
और अगर कोई अपनी किसी भी कुंजी में _ का उपयोग करता है, तो आपको बग मिलेंगे।
बीटी

1

सही नहीं है, लेकिन ज्यादातर स्थितियों में काम करेगा: निषिद्ध वर्णों को किसी अन्य चीज़ से बदल दें। चूंकि यह कुंजियों में है, इसलिए ये नए चार्ट काफी दुर्लभ होने चाहिए।

/** This will replace \ with ⍀, ^$ with '₴' and dots with ⋅  to make the object compatible for mongoDB insert. 
Caveats:
    1. If you have any of ⍀, ₴ or ⋅ in your original documents, they will be converted to \$.upon decoding. 
    2. Recursive structures are always an issue. A cheap way to prevent a stack overflow is by limiting the number of levels. The default max level is 10.
 */
encodeMongoObj = function(o, level = 10) {
    var build = {}, key, newKey, value
    //if (typeof level === "undefined") level = 20     // default level if not provided
    for (key in o) {
        value = o[key]
        if (typeof value === "object") value = (level > 0) ? encodeMongoObj(value, level - 1) : null     // If this is an object, recurse if we can

        newKey = key.replace(/\\/g, '⍀').replace(/^\$/, '₴').replace(/\./g, '⋅')    // replace special chars prohibited in mongo keys
        build[newKey] = value
    }
    return build
}

/** This will decode an object encoded with the above function. We assume the structure is not recursive since it should come from Mongodb */
decodeMongoObj = function(o) {
    var build = {}, key, newKey, value
    for (key in o) {
        value = o[key]
        if (typeof value === "object") value = decodeMongoObj(value)     // If this is an object, recurse
        newKey = key.replace(/⍀/g, '\\').replace(/^₴/, '$').replace(/⋅/g, '.')    // replace special chars prohibited in mongo keys
        build[newKey] = value
    }
    return build
}

यहाँ एक परीक्षण है:

var nastyObj = {
    "sub.obj" : {"$dollar\\backslash": "$\\.end$"}
}
nastyObj["$you.must.be.kidding"] = nastyObj     // make it recursive

var encoded = encodeMongoObj(nastyObj, 1)
console.log(encoded)
console.log( decodeMongoObj( encoded) )

और परिणाम - ध्यान दें कि मान संशोधित नहीं हैं:

{
  sub⋅obj: {
    ₴dollar⍀backslash: "$\\.end$"
  },
  ₴you⋅must⋅be⋅kidding: {
    sub⋅obj: null,
    ₴you⋅must⋅be⋅kidding: null
  }
}
[12:02:47.691] {
  "sub.obj": {
    $dollar\\backslash: "$\\.end$"
  },
  "$you.must.be.kidding": {
    "sub.obj": {},
    "$you.must.be.kidding": {}
  }
}

1

डिबग उद्देश्यों के बजाय एप्लिकेशन में इसका उपयोग करने की अनुशंसा नहीं करने के लिए कुछ बदसूरत तरीका है (केवल एम्बेडेड ऑब्जेक्ट्स पर काम करता है):

db.getCollection('mycollection').aggregate([
    {$match: {mymapfield: {$type: "object" }}}, //filter objects with right field type
    {$project: {mymapfield: { $objectToArray: "$mymapfield" }}}, //"unwind" map to array of {k: key, v: value} objects
    {$match: {mymapfield: {k: "my.key.with.dot", v: "myvalue"}}} //query
])

1

जैसा कि एक अन्य उपयोगकर्ता ने उल्लेख किया है, एन्कोडिंग / डिकोडिंग भविष्य में समस्याग्रस्त हो सकती है, इसलिए यह संभव है कि डॉट वाले सभी कुंजियों को बदलना आसान हो। यहाँ एक पुनरावर्ती कार्य है जिसे मैंने 'से बदलने के लिए बनाया है।' घटनाओं:

def mongo_jsonify(dictionary):
    new_dict = {}
    if type(dictionary) is dict:
        for k, v in dictionary.items():
            new_k = k.replace('.', '-')
            if type(v) is dict:
                new_dict[new_k] = mongo_jsonify(v)
            elif type(v) is list:
                new_dict[new_k] = [mongo_jsonify(i) for i in v]
            else:
                new_dict[new_k] = dictionary[k]
        return new_dict
    else:
        return dictionary

if __name__ == '__main__':
    with open('path_to_json', "r") as input_file:
        d = json.load(input_file)
    d = mongo_jsonify(d)
    pprint(d)

आप इस कोड को '$' को भी बदलने के लिए संशोधित कर सकते हैं, क्योंकि यह एक अन्य चरित्र है जो मोंगो कुंजी में अनुमति नहीं देगा।


0

PHP के लिए मैं अवधि के लिए HTML मान को प्रतिस्थापित करता हूं। वह है "."

यह इस तरह MongoDB में संग्रहीत करता है:

  "validations" : {
     "4e25adbb1b0a55400e030000" : {
     "associate" : "true" 
    },
     "4e25adb11b0a55400e010000" : {
       "associate" : "true" 
     } 
   } 

और PHP कोड ...

  $entry = array('associate' => $associate);         
  $data = array( '$set' => array( 'validations.' . str_replace(".", `"."`, $validation) => $entry ));     
  $newstatus = $collection->update($key, $data, $options);      


0

आप इसे स्टोर कर सकते हैं जैसा कि यह है और बहुत बाद में परिवर्तित करें

मैंने इस उदाहरण को Livescript पर लिखा था। आप इसे eval करने के लिए lifecript.net वेबसाइट का उपयोग कर सकते हैं

test =
  field:
    field1: 1
    field2: 2
    field3: 5
    nested:
      more: 1
      moresdafasdf: 23423
  field3: 3



get-plain = (json, parent)->
  | typeof! json is \Object => json |> obj-to-pairs |> map -> get-plain it.1, [parent,it.0].filter(-> it?).join(\.)
  | _ => key: parent, value: json

test |> get-plain |> flatten |> map (-> [it.key, it.value]) |> pairs-to-obj

यह उत्पादन होगा

{"field.field1":1,
 "field.field2":2,
 "field.field3":5,
 "field.nested.more":1,
 "field.nested.moresdafasdf":23423,
 "field3":3}


0

आपको मेरी टिप दें: आप ऑब्जेक्ट को बचाने के लिए JSON.stringify का उपयोग कर सकते हैं / सरणी में कुंजी नाम में डॉट्स हैं, फिर डेटाबेस से डेटा प्राप्त करने के लिए JSON.parse के साथ ऑब्जेक्ट को प्रोसेस करने के लिए स्ट्रिंग को पार्स करें।

एक और समाधान: अपने स्कीमा को पुनर्संरचना करें जैसे:

key : {
"keyName": "a.b"
"value": [Array]
}

0

नवीनतम MongoDB एक डॉट के साथ कुंजियों का समर्थन करता है, लेकिन java MongoDB-ड्राइवर समर्थन नहीं कर रहा है। इसलिए इसे जावा में काम करने के लिए, मैंने java-mongo- ड्राइवर के जीथब रेपो से कोड खींचा और उनके isValid Key फंक्शन में तदनुसार बदलाव किए, नए जार बनाए, अब इसका उपयोग कर रहा है।


0

डॉट ( .) या डॉलर ( $) को अन्य वर्णों के साथ बदलें जो वास्तविक दस्तावेज़ में कभी भी उपयोग नहीं किए जाएंगे। और दस्तावेज़ को पुनः प्राप्त करते समय डॉट ( .) या डॉलर ( $) को पुनर्स्थापित करें । रणनीति उस डेटा को प्रभावित नहीं करेगी जो उपयोगकर्ता पढ़ता है।

आप सभी वर्णों में से चरित्र का चयन कर सकते हैं ।


0

यह विचित्र है, मैंगोज का उपयोग करते हुए, मैं डॉट के साथ एक दस्तावेज बना सकता हूं यदि मैं खुद को सेट करता हूं, हालांकि मैं _आईडी उत्पन्न होने पर दस्तावेज नहीं बना सकता हूं:

काम करेगा:

db.testcollection.save({"_id": "testdocument", "dot.ted.": "value"}, (err, res) => {
    console.log(err, res);
});

काम नहीं करता:

db.testcollection.save({"dot.ted": "value"}, (err, res) => {
    console.log(err, res);
});

मैंने पहले सोचा था कि एक डॉट कुंजी के साथ एक दस्तावेज़ को अद्यतन करने के लिए भी काम किया है, लेकिन इसकी पहचान एक उपकुंजी के रूप में डॉट की पहचान करना है!

यह देखकर कि कैसे मोंगोज़ डॉट (उपकुंजी) को संभालता है, मैं यह सुनिश्चित करने जा रहा हूं कि मेरी कुंजियों में डॉट न हो।


0

@JohnnyHK ने जो उल्लेख किया है, जैसे कि विराम चिह्न हटाएं या '।' जब आपकी डेटा बड़े डेटासेट में जमा होने लगती है, तो आपकी कुंजी से यह बहुत बड़ी समस्याएँ पैदा करेगा। यह विशेष रूप से समस्याओं का कारण होगा जब आप कुल संचालकों को $ मर्ज कहते हैं, जिन्हें कुंजियों तक पहुंचने और तुलना करने की आवश्यकता होती है जो एक त्रुटि फेंक देंगे। मैंने इसे कठिन तरीके से सीखा है कृपया उन लोगों के लिए दोहराएं जो बाहर शुरू कर रहे हैं।


-2

/home/user/anaconda3/lib/python3.6/site-packages/pymongo/collection.py

यह त्रुटि संदेशों में मिला। अगर आप का उपयोग करें anaconda(यदि नहीं संवाददाता फ़ाइल खोजने), बस से मान बदलने check_keys = Trueके लिए Falseऊपर कहा गया है फ़ाइल में। यह काम करेंगे!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.