mongo는 점 (.) 또는 달러 기호 ($)가있는 키 삽입을 허용하지 않는 것 같지만 mongoimport 도구를 사용하여 점이 포함 된 JSON 파일을 가져 오면 제대로 작동했습니다. 운전자가 해당 요소를 삽입하려는 것에 대해 불평하고 있습니다.
다음은 데이터베이스에서 문서의 모습입니다.
{
"_id": {
"$oid": "..."
},
"make": "saab",
"models": {
"9.7x": [
2007,
2008,
2009,
2010
]
}
}
내가이 모든 일을 잘못하고 있고 외부 데이터 (예 : 모델)와 함께 해시 맵을 사용해서는 안됩니까? 아니면 어떻게 든 점을 이스케이프 할 수 있습니까? 어쩌면 나는 너무 많은 Javascript와 비슷하다고 생각하고 있습니다.
답변
답변
다른 답변에서 언급했듯이 MongoDB는 필드 이름 에 대한 제한으로 인해 $
또는 .
문자를 맵 키로 허용하지 않습니다 . 그러나 달러 기호 연산자 에서 언급 했듯이이 제한 사항을 이스케이프 한다고해서 이러한 키가있는 문서 를 삽입 할 수있는 것은 아닙니다. 문서를 업데이트하거나 쿼리 할 수 없습니다.
단순히 교체의 문제 .
와 함께 [dot]
나 U+FF0E
(이 페이지에 다른 곳에서 언급 한 바와 같이이) 어떤 사용자가 합법적으로 키 저장하려고 할 때 발생한다 [dot]
또는 U+FF0E
?
Fantom의 afMorphia 드라이버 가 취하는 접근 방식 은 Java와 유사한 유니 코드 이스케이프 시퀀스를 사용하지만 이스케이프 문자가 먼저 이스케이프되도록하는 것입니다. 본질적으로 다음과 같은 문자열 대체가 이루어집니다 (*).
\ --> \\
$ --> \u0024
. --> \u002e
나중에 MongoDB 에서 맵 키를 읽을 때 역방향 교체가 수행됩니다 .
또는 Fantom 코드에서 :
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는 실제로 Java의 유니 코드 이스케이프 구문에 언급 된대로 전체 / 적절한 유니 코드 이스케이프 규칙을 수행 하지만 설명 된 대체 시퀀스도 잘 작동합니다.
답변
몽고의 워드 프로세서 와 같은 잘못된 문자를 교체 할 것을 제안 $
하고 .
자신의 유니 코드 등가물.
이러한 상황에서 키는 예약 된 $ 및을 대체해야합니다. 문자. 모든 문자로 충분하지만 U + FF04 (예 : “$”) 및 U + FF0E (예 : “.”)와 같은 유니 코드 전체 너비를 사용하는 것이 좋습니다.
답변
MongoDB의 최신 안정 버전 (v3.6.1)은 현재 키 또는 필드 이름에 점 (.)을 지원합니다.
답변
방금 구현 한 솔루션 중 정말 만족 스럽습니다. 키 이름과 값을 두 개의 개별 필드로 분할하는 것입니다. 이렇게하면 문자를 똑같이 유지할 수 있으며 구문 분석 악몽에 대해 걱정할 필요가 없습니다. 문서는 다음과 같습니다.
{
...
keyName: "domain.com",
keyValue: "unregistered",
...
}
keyName 및 keyValuefind
필드 에서 a 를 수행하여 쉽게 쿼리 할 수 있습니다 .
그래서 대신 :
db.collection.find({"domain.com":"unregistered"})
실제로 예상대로 작동하지 않을 경우 다음을 실행합니다.
db.collection.find({keyName:"domain.com", keyValue:"unregistered"})
예상 된 문서를 반환합니다.
답변
값 대신 키에 해시를 사용한 다음 해당 값을 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) ];
}
답변
지금 지원됩니다
MongoDb 3.6 이상 에서는 필드 이름에서 점 과 달러 를 모두 지원 합니다. JIRA 아래 참조 : https://jira.mongodb.org/browse/JAVA-2810
Mongodb를 3.6 이상으로 업그레이드하는 것이 가장 좋은 방법입니다.