Dấu chấm MongoDB (.) Trong tên khóa


93

Có vẻ như mongo không cho phép chèn các khóa có dấu chấm (.) Hoặc dấu đô la ($) tuy nhiên khi tôi nhập tệp JSON có chứa dấu chấm trong đó bằng công cụ mongoimport, nó hoạt động tốt. Người lái xe đang phàn nàn về việc cố gắng chèn phần tử đó.

Đây là tài liệu trông như thế nào trong cơ sở dữ liệu:

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

Tôi làm điều này hoàn toàn sai và không nên sử dụng bản đồ băm như vậy với dữ liệu bên ngoài (tức là các mô hình) hay tôi có thể thoát khỏi dấu chấm bằng cách nào đó? Có lẽ tôi đang nghĩ quá nhiều về Javascript.


Câu trả lời:


85

MongoDB không hỗ trợ các khóa có dấu chấm nên bạn sẽ phải xử lý trước tệp JSON của mình để xóa / thay thế chúng trước khi nhập hoặc bạn sẽ tự đặt ra cho mình đủ loại vấn đề.

Không có một giải pháp tiêu chuẩn nào cho vấn đề này, cách tiếp cận tốt nhất quá phụ thuộc vào các chi tiết cụ thể của tình huống. Nhưng tôi sẽ tránh bất kỳ cách tiếp cận bộ mã hóa / giải mã khóa nào nếu có thể vì bạn sẽ tiếp tục phải trả sự bất tiện của điều đó vĩnh viễn, trong đó việc tái cấu trúc JSON có lẽ sẽ là chi phí một lần.


1
Tôi không nghĩ rằng có một cách tiêu chuẩn, cách tiếp cận tốt nhất quá phụ thuộc vào các chi tiết cụ thể của tình huống. Nhưng tôi sẽ tránh bất kỳ phương pháp mã hóa / giải mã khóa nào nếu có thể vì bạn sẽ tiếp tục phải trả sự bất tiện của điều đó vĩnh viễn, trong đó một cơ cấu lại JSON có lẽ sẽ là chi phí một lần.
JohnnyHK

8
Lại rơi vào tình huống này. Điều này dường như không xảy ra quá nhiều với các tên khóa ứng dụng, mà chúng ta có thể kiểm soát và thường cần truy vấn, nhưng với dữ liệu do người dùng cung cấp trong cấu trúc dữ liệu lồng nhau, mà chúng ta không thể kiểm soát, nhưng (a) muốn lưu trữ trong Mongo , (b) chúng tôi biết điều này có thể xảy ra trong các trường cụ thể nào (ví dụ: modelsở đây) và (c) chúng tôi không cần truy vấn chúng theo tên khóa trong Mongo. Vì vậy, một mẫu mà tôi đã giải quyết là JSON.stringifylưu trường này và 'JSON.parse` khi truy xuất.
nguyên mẫu

16
Nếu phải, bạn có thể cung cấp tùy chọn {check_keys: false} để bỏ qua vấn đề này.
Tzury Bar Yochay

5
@TzuryBarYochay OMG bạn đã tìm thấy MongoDB tương đương với đoạn tây bắc. Tôi nghĩ đây phải là câu trả lời được chấp nhận.
nguyên mẫu

2
@emarel db.collection_foo.update ({this: "that"}, {$ set: {a: "b"}}, {check_keys: false})
Tzury Bar Yochay

22

Như đã đề cập trong các câu trả lời khác, MongoDB không cho phép $hoặc .ký tự làm khóa bản đồ do các hạn chế về tên trường . Tuy nhiên, như đã đề cập trong Dollar Sign Operator Thoát khỏi hạn chế này không ngăn bạn chèn tài liệu bằng các khóa như vậy, nó chỉ ngăn bạn cập nhật hoặc truy vấn chúng.

Vấn đề chỉ cần thay thế .bằng [dot]hoặc U+FF0E(như đã đề cập ở những nơi khác trên trang này) là, điều gì sẽ xảy ra khi người dùng muốn lưu trữ khóa [dot]hoặc U+FF0E?

Một cách tiếp cận mà trình điều khiển afMorphia của Fantom thực hiện, là sử dụng trình tự thoát unicode tương tự như của Java, nhưng đảm bảo ký tự thoát được thoát trước. Về bản chất, các chuỗi thay thế sau được thực hiện (*):

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

Thay thế ngược lại được thực hiện khi các khóa bản đồ sau đó được đọc từ MongoDB.

Hoặc trong mã Fantom :

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

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

Thời điểm duy nhất người dùng cần biết về các chuyển đổi đó là khi xây dựng các truy vấn cho các khóa như vậy.

Do việc lưu trữ dotted.property.namestrong cơ sở dữ liệu cho mục đích cấu hình là phổ biến, tôi tin rằng cách tiếp cận này phù hợp hơn khi chỉ cần cấm tất cả các khóa bản đồ như vậy.

(*) afMorphia thực sự thực hiện các quy tắc thoát unicode đầy đủ / thích hợp như đã đề cập trong cú pháp thoát Unicode trong Java nhưng trình tự thay thế được mô tả cũng hoạt động tốt.


Nên sử dụng //gđể thay thế tất cả các lần xuất hiện chứ không chỉ lần đầu. Ngoài ra, sử dụng các giá trị tương đương chiều rộng đầy đủ như trong câu trả lời của Martin Konecny ​​có vẻ là một ý kiến ​​hay. Cuối cùng, một dấu gạch chéo ngược là đủ cho mã hóa. key.replace(/\./g, '\uff0e').replace(/\$/g, '\uff04').replace(/\\/g, '\uff3c')
cw '

1
@cw '- Mã có cú pháp giống Java, vì vậy thay thế thực sự thay thế tất cả các lần xuất hiện và dấu gạch chéo ngược kép là bắt buộc để thoát dấu gạch chéo ngược. Và một lần nữa, bạn cần giới thiệu một số hình thức thoát hiểm để đảm bảo tất cả các trường hợp được bảo hiểm. Ai đó, tại một số thời điểm, có thể thực sự muốn một khóa của U+FF04.
Steve Eynon

2
Hóa ra, Mongodb Hỗ trợ dấu chấm và đô la trong các phiên bản mới nhất của nó. Xem: - stackoverflow.com/a/57106679/3515086
Abhidemon

18

Các tài liệu Mongo đề xuất thay thế các ký tự bất hợp pháp như $.bằng các ký tự tương đương unicode của chúng.

Trong những trường hợp này, các khóa sẽ cần thay thế $ và. nhân vật. Bất kỳ ký tự nào là đủ, nhưng hãy cân nhắc sử dụng các ký tự tương đương chiều rộng đầy đủ Unicode: U + FF04 (tức là “$”) và U + FF0E (tức là “.”).


74
Điều đó nghe có vẻ giống như một công thức để gỡ lỗi đau đầu trên đường.
không ai vào

2
@AndrewMedico, @tamlyn - Tôi nghĩ rằng các tài liệu có nghĩa là một cái gì đó giống nhưdb.test.insert({"field\uff0ename": "test"})
P. Myer Nore

4
-1 A. Đó là một ý tưởng khủng khiếp - điều gì sẽ xảy ra nếu ai đó thực sự đang cố gắng sử dụng các ký tự unicode đó làm khóa? Sau đó, bạn có một lỗi im lặng sẽ làm gì ai biết được hệ thống của bạn. Đừng sử dụng các phương pháp thoát mơ hồ như vậy. B. the Mongo docs không còn nói như vậy nữa, có lẽ vì ai đó đã nhận ra đó là một ý tưởng khủng khiếp
BT

7
@SergioTishedsev Tôi đã yêu cầu họ xóa đề xuất:) github.com/mongodb/docs/commit/…
BT

2
@BT: ngả mũ chào bạn, thưa bạn :)
Sergio Tishedsev 15/11/16

15

Phiên bản ổn định mới nhất (v3.6.1) của MongoDB hiện hỗ trợ dấu chấm (.) Trong các phím hoặc tên trường.

Tên trường hiện có thể chứa các ký tự dấu chấm (.) Và đô la ($)


10
Ngay cả khi máy chủ hỗ trợ nó ngay bây giờ, trình điều khiển vẫn kiểm tra các phím $ và dấu chấm và không chấp nhận chúng. Do đó về mặt lý thuyết Mongo chỉ hỗ trợ dấu chấm và ký tự đô la. Trên thực tế, cái này vẫn chưa thể sử dụng được :(
JMax

Có thể bạn đang sử dụng một số ứng dụng cũ hoặc không tương thích. Tôi đã sử dụng điều này trên các máy chủ sản xuất của mình mà không hề đổ mồ hôi. Tôi đã kiểm tra các ứng dụng khách NodeJS và Java.
h4ck3d

Với Java, nó hoàn toàn không hoạt động! Hãy thử lệnh sau: mongoClient.getDatabase("mydb").getCollection("test").insertOne(new Document("value", new Document("key.with.dots", "value").append("$dollar", "value")));Không thể sử dụng mongodb-driver.3.6.3 và MongoDB 3.6.3.
JMax 23/03/18

1
Thật vậy, tôi vừa thử với một thiết lập mongodb-4.1.1pymongo-3.7.1. Tôi có thể thêm các tài liệu có chứa các phím với .với robomongo nhưng không phải từ pymongo, nó Sill tăng lương InvalidDocument: key '1.1' must not contain '.'Chúc nó đã được cố định bởi bây giờ ...
Học tập là một mớ hỗn độn

Tôi đã thử với máy chủ mongodb 4.0.9 và trình điều khiển java 3.10.2 nhưng nó không chấp nhận dấu chấm trong tên khóa. thật lạ là khi thử sử dụng robomongo thì nó hoạt động ...
xyzt

12

Một giải pháp mà tôi vừa thực hiện mà tôi thực sự hài lòng là tách tên và giá trị khóa thành hai trường riêng biệt. Bằng cách này, tôi có thể giữ các ký tự giống hệt nhau và không phải lo lắng về bất kỳ cơn ác mộng phân tích cú pháp nào. Tài liệu sẽ trông giống như:

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

Bạn vẫn có thể truy vấn điều này dễ dàng, chỉ bằng cách thực hiện findtrên các trường keyName keyValue .

Vì vậy, thay vì:

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

mà không thực sự hoạt động như mong đợi, bạn sẽ chạy:

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

và nó sẽ trả về tài liệu mong đợi.


Bạn làm nó như thế nào? Bạn có thể vui lòng giúp tôi với trường hợp tương tự.
hồ sơ

Tôi đã thêm một ví dụ truy vấn. cái đó có giúp ích không?
Steve

10

Bạn có thể thử sử dụng hàm băm trong khóa thay vì giá trị và sau đó lưu trữ giá trị đó trong giá trị 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
    ]
}

Sau đó, bạn sẽ truy cập các mô hình bằng cách sử dụng hàm băm sau này.

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

1
Tôi thích điều này, giải pháp sạch với băm 1 chiều và thực sự giống với cách mọi thứ hoạt động dưới mui xe.
Michael Yagudaev

3
Vấn đề với việc sử dụng hàm băm làm khóa là chúng không được đảm bảo là duy nhất và chúng thường xuyên tạo ra xung đột . Cộng với việc tính toán một hàm băm mật mã mỗi khi bạn muốn truy cập vào bản đồ dường như không phải là giải pháp tối ưu nhất đối với tôi.
Steve Eynon

2
Tại sao điều này tốt hơn thay thế dấu chấm bằng một ký tự hoặc chuỗi ký tự đặc biệt?
B Seven

Chuyển đổi chuỗi sang base64 tốt hơn nhiều.
Zen

8

Nó được hỗ trợ ngay bây giờ

MongoDb 3.6 trở đi hỗ trợ cả dấu chấmđô la trong tên trường. Xem bên dưới JIRA: https://jira.mongodb.org/browse/JAVA-2810

Nâng cấp Mongodb của bạn lên 3.6+ nghe có vẻ là cách tốt nhất.


Đây là câu trả lời tốt nhất ở đây. : +1
hello_abhishek

3
3.6 có thể lưu trữ chúng, vâng, nhưng nó được không chưa được hỗ trợ, có thể ném lỗi lái xe, và có thể phá vỡ truy vấn / cập nhật: hạn chế : "Các Query Language MongoDB có thể không phải lúc nào ý nghĩa thể hiện truy vấn trên các tài liệu có tên trường chứa các ký tự (xem Server- 30575). Cho đến khi hỗ trợ được thêm vào ngôn ngữ truy vấn, việc sử dụng $ và. Trong tên trường không được khuyến nghị và không được hỗ trợ bởi trình điều khiển MongoDB chính thức. "
JeremyDouglass

4

Từ tài liệu MongoDB "the '." ký tự không được xuất hiện ở bất kỳ đâu trong tên khóa ". Có vẻ như bạn sẽ phải đưa ra một lược đồ mã hóa hoặc làm mà không.


4

Bạn sẽ cần phải thoát khỏi các phím. Vì có vẻ như hầu hết mọi người không biết cách thoát chuỗi đúng cách, đây là các bước:

  1. chọn một ký tự thoát (tốt nhất nên chọn một ký tự hiếm khi được sử dụng). Ví dụ. '~'
  2. Để thoát, trước tiên hãy thay thế tất cả các trường hợp của ký tự thoát bằng một số chuỗi được thêm trước bằng ký tự thoát của bạn (ví dụ: '~' -> '~ t'), sau đó thay thế bất kỳ ký tự hoặc chuỗi nào bạn cần để thoát bằng một số chuỗi được thêm trước bằng ký tự thoát của bạn . Ví dụ. '.' -> '~ p'
  3. Để unescape, trước tiên hãy xóa chuỗi thoát khỏi tất cả các phiên bản của chuỗi thoát thứ hai của bạn (ví dụ: '~ p' -> '.'), Sau đó chuyển chuỗi ký tự thoát của bạn thành một ký tự thoát duy nhất (ví dụ: '~ s' -> '~ ')

Ngoài ra, hãy nhớ rằng mongo cũng không cho phép các khóa bắt đầu bằng '$', vì vậy bạn phải làm điều gì đó tương tự ở đó

Đây là một số mã thực hiện nó:

// 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, '~')
}

Việc thoát này vẫn có thể bị hỏng, nếu bạn có các chuỗi như '. ~ P.'. Ở đây chuỗi thoát sẽ là '~ p ~~ p ~ p'. Unescaping sẽ cung cấp cho bạn '. ~ ..', khác với chuỗi thực.
jvc

1
@jvc Bạn nói đúng! Tôi đã sửa các hàm thoát ví dụ và giải thích. Hãy cho tôi biết nếu chúng vẫn còn hỏng!
BT

3

Một câu trả lời muộn, nhưng nếu bạn sử dụng Spring và Mongo, Spring có thể quản lý chuyển đổi cho bạn MappingMongoConverter. Đó là giải pháp của JohnnyHK nhưng do Spring xử lý.

@Autowired
private MappingMongoConverter converter;

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

Nếu Json được lưu trữ của bạn là:

{ "axxxb" : "value" }

Qua Spring (MongoClient), nó sẽ được đọc là:

{ "a.b" : "value" }

yêu cầu một bean loại 'org.springframework.data.mongodb.core.convert.MappingMongoConverter' mà không thể tìm thấy.
Sathya Narayan C

1

Tôi sử dụng lối thoát sau trong JavaScript cho mỗi khóa đối tượng:

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

Điều tôi thích về nó là nó chỉ thay thế $ở phần đầu và nó không sử dụng các ký tự unicode có thể khó sử dụng trong bảng điều khiển. _đối với tôi dễ đọc hơn nhiều so với một ký tự unicode. Nó cũng không thay thế một bộ ký tự đặc biệt ( $, .) bằng một bộ khác (unicode). Nhưng thoát đúng cách với truyền thống \.


3
Và nếu ai đó sử dụng dấu _ trong bất kỳ khóa nào của họ, bạn sẽ gặp lỗi.
BT

1

Không hoàn hảo, nhưng sẽ hoạt động trong hầu hết các tình huống: thay thế các ký tự bị cấm bằng một thứ khác. Vì nó nằm trong khóa, những ký tự mới này sẽ khá hiếm.

/** 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
}

Đây là một bài kiểm tra:

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

và kết quả - lưu ý rằng các giá trị không được sửa đổi:

{
  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

Có một số cách xấu để truy vấn nó không được khuyến khích sử dụng trong ứng dụng thay vì cho mục đích gỡ lỗi (chỉ hoạt động trên các đối tượng được nhúng):

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

Như một người dùng khác đã đề cập, việc mã hóa / giải mã điều này có thể trở thành vấn đề trong tương lai, vì vậy việc thay thế tất cả các phím có dấu chấm có thể dễ dàng hơn. Đây là một hàm đệ quy mà tôi đã thực hiện để thay thế các phím bằng '.' lần xuất hiện:

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)

Bạn cũng có thể sửa đổi mã này để thay thế '$', vì đó là một ký tự khác mà mongo sẽ không cho phép trong khóa.


0

Đối với PHP, tôi thay thế giá trị HTML cho dấu chấm. Đó là"." .

Nó lưu trữ trong MongoDB như thế này:

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

và mã PHP ...

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

0

Các cặp Lodash sẽ cho phép bạn thay đổi

{ 'connect.sid': 's:hyeIzKRdD9aucCc5NceYw5zhHN5vpFOp.0OUaA6' }

thành

[ [ 'connect.sid',
's:hyeIzKRdD9aucCc5NceYw5zhHN5vpFOp.0OUaA6' ] ]

sử dụng

var newObj = _.pairs(oldObj);

0

Bạn có thể lưu trữ nó như cũ và chuyển đổi thành khá sau

Tôi đã viết ví dụ này trên Livescript. Bạn có thể sử dụng trang web livescript.net để đánh giá nó

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

Nó sẽ sản xuất

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


0

Cho bạn mẹo của tôi: Bạn có thể sử dụng JSON.stringify để lưu Đối tượng / Mảng chứa tên khóa có dấu chấm, sau đó phân tích cú pháp chuỗi thành Đối tượng bằng JSON. Phân tích cú pháp để xử lý khi lấy dữ liệu từ cơ sở dữ liệu

Một giải pháp khác: Cấu trúc lại lược đồ của bạn như:

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

0

MongoDB mới nhất không hỗ trợ các phím có dấu chấm, nhưng trình điều khiển java MongoDB không hỗ trợ. Vì vậy, để làm cho nó hoạt động trong Java, tôi đã lấy mã từ github repo của java-mongo-driver và thực hiện các thay đổi tương ứng trong chức năng isValid Key của chúng, tạo jar mới từ nó, sử dụng nó ngay bây giờ.


0

Thay thế dấu chấm ( .) hoặc đô la ( $) bằng các ký tự khác sẽ không bao giờ được sử dụng trong tài liệu thực. Và khôi phục dấu chấm (. ) hoặc đô la ( $) khi truy xuất tài liệu. Chiến lược sẽ không ảnh hưởng đến dữ liệu mà người dùng đọc.

Bạn có thể chọn ký tự từ tất cả các ký tự .


0

Điều kỳ lạ là, bằng cách sử dụng mongojs, tôi có thể tạo tài liệu có dấu chấm nếu tôi tự đặt _id, tuy nhiên tôi không thể tạo tài liệu khi _id được tạo:

Làm việc:

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

Không hoạt động:

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

Đầu tiên tôi nghĩ rằng cập nhật tài liệu bằng khóa dấu chấm cũng có tác dụng, nhưng nó xác định dấu chấm như một khóa con!

Xem cách mongojs xử lý dấu chấm (khóa con), tôi sẽ đảm bảo các khóa của mình không chứa dấu chấm.


0

Giống như những gì @JohnnyHK đã đề cập, hãy xóa dấu chấm câu hoặc '.' từ các khóa của bạn vì nó sẽ tạo ra các vấn đề lớn hơn nhiều khi dữ liệu của bạn bắt đầu tích lũy thành một tập dữ liệu lớn hơn. Điều này sẽ gây ra sự cố, đặc biệt là khi bạn gọi các toán tử tổng hợp như $ merge yêu cầu truy cập và so sánh các khóa sẽ gây ra lỗi. Tôi đã học nó một cách khó khăn xin đừng lặp lại đối với những người đang bắt đầu.


-2

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

Tìm thấy nó trong thông báo lỗi. Nếu bạn sử dụng anaconda(tìm tệp tương ứng nếu không), chỉ cần thay đổi giá trị từ check_keys = Truethành Falsetrong tệp đã nêu ở trên. Điều đó sẽ hoạt động!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.