개인 정보 설정이 제공된 것과 일치하는 문서와 개인 정보 설정 (예 : 공용)이없는 문서를 선택하려고합니다.
현재 동작은 그 나는 다른 컬렉션에 참조 된 개체 ID의 배열과 스키마가있는 경우 :
privacy: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Category',
index: true,
required: true,
default: []
}],
을 그리고 우리의 경우 함량, 내 범주와 대중들에 대한 모든 콘텐츠를 필터링 할 개인 정보 보호 설정이 없습니다. 즉 하늘의 배열은 []
우리는 현재 또는 쿼리
{"$or":[
{"privacy": {"$size": 0}},
{"privacy": {"$in":
["5745bdd4b896d4f4367558b4","5745bd9bb896d4f4367558b2"]}
}
]}
와 나는 단지 [] 하나 문에서 $의 비교 옵션을 하늘의 배열을 제공하여 쿼리 사랑한다고 쿼리합니다.
db.emptyarray.insert({a:1})
db.emptyarray.insert({a:2, b:null})
db.emptyarray.insert({a:2, b:[]})
db.emptyarray.insert({a:3, b:["perm1"]})
db.emptyarray.insert({a:3, b:["perm1", "perm2"]})
db.emptyarray.insert({a:3, b:["perm1", "perm2", []]})
> db.emptyarray.find({b:[]})
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce0"), "a" : 2, "b" : [ ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce3"), "a" : 3, "b" : [ "perm1", "perm2", [ ] ] }
> db.emptyarray.find({b:{$in:[]}})
> db.emptyarray.find({b:{$in:[[], "perm1"]}})
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce0"), "a" : 2, "b" : [ ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce1"), "a" : 3, "b" : [ "perm1" ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce2"), "a" : 3, "b" : [ "perm1", "perm2" ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce3"), "a" : 3, "b" : [ "perm1", "perm2", [ ] ] }
> db.emptyarray.find({b:{$in:[[], "perm1", null]}})
{ "_id" : ObjectId("5a305f3dd89e8a887e629cde"), "a" : 1 }
{ "_id" : ObjectId("5a305f3dd89e8a887e629cdf"), "a" : 2, "b" : null }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce0"), "a" : 2, "b" : [ ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce1"), "a" : 3, "b" : [ "perm1" ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce2"), "a" : 3, "b" : [ "perm1", "perm2" ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce3"), "a" : 3, "b" : [ "perm1", "perm2", [ ] ] }
> db.emptyarray.find({b:{$in:[[]]}})
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce0"), "a" : 2, "b" : [ ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce3"), "a" : 3, "b" : [ "perm1", "perm2", [ ] ] }
어쩌면이 같은 : MongoDB를 가능한 어느
"privacy_locations":{
"$in": ["5745bdd4b896d4f4367558b4","5745bd9bb896d4f4367558b2",[]]
}
그러나이 쿼리, 그것은 주조 오류가 발생합니다 코드에서 콘솔 (CLI)에서 작동하지만,하지 :
{
"message":"Error in retrieving records from db.",
"error":
{
"message":"Cast to ObjectId failed for value \"[]\" at ...
}
}
이제 스키마가 ObjectId로 정의 되었기 때문에 캐스트가 발생하는 것을 완벽하게 이해합니다.
하지만이 방법에는 가능한 두 가지 시나리오가 없습니다.
$ in 문 내에서 null 옵션이나 빈 배열을 (MongoDB에서) 쿼리 할 수 있다고 생각합니다.
array: {$in:[null, [], [option-1, option-2]}
이 맞습니까?
내 문제 (옵션 또는 빈에서는 선택할 수 없음)에 대한 최선의 해결책은 빈 배열이 예를 들어 ALL의 수정 옵션을 가진 배열이 될 수 있다고 생각 해왔다. 프라이버시를위한 설정은 그것이 현재 설정되지 않은 경우 ALL이 아니라 설정 된 경우 모든 것을 의미하는 ALL을 의미합니다.
기존 코드의 주요 리팩터를 원하지는 않지만 더 나은 쿼리를 만들 수 있는지 또는 성능이 좋은 쿼리를 만들 수 있는지 확인해야합니다.
오늘 우리는 인덱스에 문제가있는 $ OR 문으로 작업하는 쿼리가 있습니다. 그리고 비록 그것이 빠르더라도, 나는 버그로 간주되지 않더라도이 문제에주의를 기울이고 싶었습니다.
모든 의견이나 안내를 부탁드립니다.
"에 대한 쿼리 문서 {개인 정보 보호 : {$에서 [[]]가}}. 오류로 표시된 바와 같이, 하늘의 배열이 유효한 ObjectId가 아니기 때문에 검증을 실패합니다" []가 ObjectID를 나타내는 것으로 생각하지 않습니다. 어떤 배열의 내용입니다. 0 개의 ObjectId의 배열은 비어있는 ARRAY []입니다. 그리고 나는 objectInd 중 하나가 맞지 않기 때문에 objectid 또는이 경우에는 문자열을 포함한다면 주어진 $ 옵션이 주어진 옵션을 통과한다고 생각합니까? 옵션을 통해 ObjectId로 캐스팅되고 NULL 또는 빈 배열 옵션을 평가할 수 있어야합니다. 프라이버시가 null이면 OID가 –
mongo의 문서에서'$ in' : "_ 필드에 배열이 있으면'$ in' 연산자는 필드에 값과 일치하는 적어도 하나의 요소가 들어있는 배열을 가진 문서를 선택합니다 지정된 배열에 있습니다 (예 :, 등). " 즉, mongo는 배열의 요소를 쿼리 된 문서 속성의 배열 값과 일치하는지 확인하려고 배열을 반복합니다. 스키마는 ObjectIds의 배열임을 스키마가 선언 했으므로 Mongoose는 쿼리 문서의 모든 값을 ObjectId로 캐스팅하려고 시도합니다. 따라서이 개체는 오류를 발생시킵니다. –
privacy가 emtpy [] like {privacy : []} 인 경우, [[], ObjectId ('xxxx')의 $는 개인 정보 보호의 가치이기 때문에 []와 일치합니다. where 절과 결과가 내가 필요한 것이 아닙니다. CLI 예제를 추가했습니다. Foo.find(). where ({privacy : {$ in : [[]]}})는 하나의 문서가 빈 배열을 가지므로 하나의 문서 만 반환해야하고, 다른 하나는 인스턴스가있는 배열을가집니다. ObjectId. 다르게 써주세요. 프라이버시 유형이 ObjectId 인 경우 objectid 또는 null 일 수 있습니다. OID 배열 인 경우 Null, [] 또는 값을 유지할 수 있습니다. 이 3 가지 값을 보유하기 위해 혼합 유형이 필요하지 않습니다. –