부울 필드를 "참이 아님"(예 : 거짓 또는 존재하지 않음)으로 쿼리
나는 MongoDB 쿼리에서 매우 기본적인 것을 놓치고 있다고 확신합니다.이 간단한 조건을 얻을 수 없습니다.
이 컬렉션 고려
> db.tests.find()
{ "_id" : ObjectId("..."), "name" : "Test1" , "deleted" : true}
{ "_id" : ObjectId("..."), "name" : "Test2" , "deleted" : false}
{ "_id" : ObjectId("..."), "name" : "Test3" }
"삭제되지 않은"모든 항목을 쿼리하고 싶습니다.
"삭제됨"플래그가 true로 설정된 항목을 찾는 방법을 알고 있습니다.
> db.tests.find({deleted:true})
{ "_id" : ObjectId("..."), "name" : "Test1" , "deleted" : true}
그러나 그렇지 않은 모든 항목을 어떻게 찾 "deleted"
습니까 (예 : 위의 쿼리를 부정하거나 다른 말로 "deleted"
필드가 없거나 값이있는 항목)false
추측 해 본 것 (웃지 말아주세요 ...)
> db.tests.find({$not : {deleted: true}})
(결과를 반환하지 않음)
> db.tests.find({$not : {$eq:{deleted:true}}})
오류 : { "$ err": "잘못된 연산자 : $ eq", "code": 10068}
> db.tests.find({deleted:{$not: true}})
오류 : { "$ err": "$ not의 잘못된 사용", "code": 13041}
> db.tests.find({deleted:{$not: {$eq:true}}})
오류 : { "$ err": "$ not의 잘못된 사용", "code": 13034}
내가 무엇을 놓치고 있습니까?
db.tests.find({deleted: {$ne: true}})
어디 $ne
를 의미합니다 "동일하지". ( mongodb 연산자에 대한 문서 )
완전성을 위해이 작업을 수행하는 또 다른 방법은 다음과 $in
같습니다.
db.test.find({deleted: {$in: [null, false]}})
null
배열에 포함 하면 deleted
필드가 누락 된 문서를 가져옵니다 . 이 쿼리는 {deleted: 1}
현재 2.6.6 MongoDB 릴리스 의 인덱스를 사용할 수 있습니다 .
JohnnyHK가 최고의 답을 가지고 있습니다. $in
선택기 IMO 짧고 깨끗하다.
이것은 정확히 "거짓"또는 "존재하지 않음"을 테스트합니다. 그리고 색인화 될 수 있습니다.
db.tests.find({$or:[{deleted:false},{deleted:{$exists:false}}]})
인덱스를 사용한 예.
((function(){
print("creating collection 'testx' and inserting 50 trues, 50 falses, 50 non-existents");
db.testx.drop();
db.testx.ensureIndex({deleted:1});
for (var i=0;i<50;i++){
db.testx.insert({i:i,deleted:false});
};
for (var i=0;i<50;i++){
db.testx.insert({i:i,deleted:true});
};
for (var i=0;i<50;i++){
db.testx.insert({i:i});
};
var res0 = db.testx.find().explain();
var res1 = db.testx.find({deleted:false}).explain();
var res2 = db.testx.find({deleted:true}).explain();
var res3 = db.testx.find({deleted:{$exists:false}}).explain();
var res4 = db.testx.find({$or:[{deleted:false},{deleted:{$exists:false}}]}).explain();
var res5 = db.testx.find({$or:[{deleted:true},{deleted:{$exists:false}}]}).explain();
var res6 = db.testx.find({deleted:{$in:[false,null]}}).explain();
print("res0: all objects ("+res0["n"]+" found, "+res0["nscannedObjects"]+" scanned)");
print("res1: deleted is false ("+res1["n"]+" found, "+res1["nscannedObjects"]+" scanned)");
print("res2: deleted is true ("+res2["n"]+" found, "+res2["nscannedObjects"]+" scanned)");
print("res3: deleted is non-existent ("+res3["n"]+" found, "+res3["nscannedObjects"]+" scanned)");
print("res4: deleted is false or non-existent ("+res4["n"]+" found, "+res4["nscannedObjects"]+" scanned)");
print("res5: deleted is true or non-existent ("+res5["n"]+" found, "+res5["nscannedObjects"]+" scanned)");
print("res6: deleted is in [false,null] ("+res5["n"]+" found, "+res5["nscannedObjects"]+" scanned)");
})())
이것은 인쇄되어야합니다
creating collection 'testx' and inserting 50 trues, 50 falses, 50 non-existents
res0: all objects (150 found, 150 scanned)
res1: deleted is false (50 found, 50 scanned)
res2: deleted is true (50 found, 50 scanned)
res3: deleted is non-existent (50 found, 50 scanned)
res4: deleted is false or non-existent (100 found, 100 scanned)
res5: deleted is true or non-existent (100 found, 100 scanned)
res6: deleted is in [false,null] (100 found, 100 scanned)
For the case that someone needs this in an aggregation pipeline instead of find
, this is what worked for me
db.getCollection('tests').aggregate([
// ...previous operations...
{ $addFields: { "deleted_conclusion": { $cond: {
if:{ $ne: [ "$deleted", false ]}, then: { $cond: [ "$deleted", ":TRUE", ":FALSY"]}, else: ":FALSE"
}}}}
])
After adding the extra field you can go on with pipeline stages and have the information you miss
In case you are looking for mongoid syntax (I am using this in a rails app), this is what I came up with for a company's users:
2.3.1 :042 > accepted_consent = org.users.active.where(:accepted_terms_and_conditions => true).count
=> 553
2.3.1 :043 > not_accepted_yet = org.users.active.where(:accepted_terms_and_conditions.ne => true).count
=> 6331
2.3.1 :044 > 6331+553
=> 6884
2.3.1 :045 > org.users.active.count
=> 6884
'programing' 카테고리의 다른 글
Eclipse는 다음 / 이전 표시된 항목으로 이동합니다. (0) | 2020.12.03 |
---|---|
ASP.Net MVC – 리소스를 찾을 수 없음 오류 (0) | 2020.12.03 |
다른 디렉터리의 Gradle 프로젝트 필요 (0) | 2020.12.03 |
MediaCodec 및 MediaMuxer를 사용하여 비디오 인코딩 및 다중화 (0) | 2020.12.02 |
단일 저장소에 대한 작업복에 여러 커버리지 보고서를 가져옵니다. (0) | 2020.12.02 |