[MONGODB] 배열 필드가 비어 있지 않은 경우 MongoDB를 기록 찾기
MONGODB배열 필드가 비어 있지 않은 경우 MongoDB를 기록 찾기
내 기록의 모든 필드는 "사진"이라고했다. 이 필드는 문자열의 배열이다.
이 배열이 비어 있지 어디 이제 새로운 10 개 개의 레코드를 원한다.
나는 주위 검색 좀했지만, 이상하게 나는 이것에 많이 발견하지 않았습니다. 어디서 옵션 $로 읽었습니다,하지만 난 더 나은 솔루션이 기본 기능에, 그리고 경우입니다 방법 느린 궁금 해서요.
그리고 그렇다하더라도, 그것은 작동하지 않습니다
ME.find({$where: 'this.pictures.length > 0'}).sort('-created').limit(10).execFind()
아무 것도 반환하지 않습니다. 길이 비트없이 this.pictures두면 작업을 수행하지만, 그것은 또한 물론, 빈 레코드를 반환합니다.
해결법
-
==============================
1.당신은 또한 키가없는 문서가있는 경우, 당신은 사용할 수 있습니다 :
당신은 또한 키가없는 문서가있는 경우, 당신은 사용할 수 있습니다 :
ME.find({ pictures: { $exists: true, $not: {$size: 0} } })
$ 크기가 포함되어있는 경우 MongoDB를 인덱스를 사용하지 않는, 그래서 여기에 더 나은 솔루션입니다 :
ME.find({ pictures: { $exists: true, $ne: [] } })
MongoDB를 2.6 출시 된 이후, 당신은 운영자 $ GT는 비교 할 수 있지만 (이 대답에서 자세한 것을 설명을 찾을 수 있습니다) 예기치 않은 결과가 발생할 수 있습니다 :
ME.find({ pictures: { $gt: [] } })
-
==============================
2.더 특히 MongoDB를 문서에서 찾고, 함께 비트를 수수께끼 일부 후이 대답했다 :
더 특히 MongoDB를 문서에서 찾고, 함께 비트를 수수께끼 일부 후이 대답했다 :
ME.find({pictures: {$exists: true, $not: {$size: 0}}})
-
==============================
3.이것은 또한 당신을 위해 작동하지 않을 수 있습니다 :
이것은 또한 당신을 위해 작동하지 않을 수 있습니다 :
ME.find({'pictures.0': {$exists: true}});
-
==============================
4.정확도와 성능 - 당신은 쿼리 두 가지에 관심. 염두에두고, 나는 MongoDB의의 v3.0.14에서 몇 가지 다른 방법을 시험했다.
정확도와 성능 - 당신은 쿼리 두 가지에 관심. 염두에두고, 나는 MongoDB의의 v3.0.14에서 몇 가지 다른 방법을 시험했다.
TL; DR이 db.doc.find ({{$ 하였다 : nums -Infinity를}})이며 가장 신속하고 신뢰성 (I는 테스트 MongoDB의 버전 적어도).
편집 : 이것은 더 이상 MongoDB를의 V3.6에서 작동하지 않습니다! 잠재적 인 솔루션이 게시물 아래에있는 주석을 참조하십시오.
나는 비어 있지 않은 목록 / O 목록 필드 w 1K 문서, 빈 목록 1K 워드 프로세서, 5 문서를 삽입.
for (var i = 0; i < 1000; i++) { db.doc.insert({}); } for (var i = 0; i < 1000; i++) { db.doc.insert({ nums: [] }); } for (var i = 0; i < 5; i++) { db.doc.insert({ nums: [1, 2, 3] }); } db.doc.createIndex({ nums: 1 });
나는이 충분하지 않은 규모의 I 아래의 테스트에서 나처럼 진지로 성능을 가지고하는 것입니다 인식하지만, 다양한 질의의 정확성 및 선택 쿼리 계획의 동작을 제공하기에 충분합니다.
db.doc.find ({ 'nums'{ '$가 존재한다'는 true}}) (우리가 달성하려는 것에 대해) 잘못된 결과를 반환합니다.
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': {'$exists': true}}).count() 1005
--
db.doc.find ({ 'nums.0'{ '$ 존재'는 true}}) 올바른 결과를 반환하지만 그것은 또한 느린 전체 컬렉션을 스캔 (설명에 통지 COLLSCAN 단계)를 사용합니다.
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums.0': {'$exists': true}}).count() 5 MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums.0': {'$exists': true}}).explain() { "queryPlanner": { "plannerVersion": 1, "namespace": "test.doc", "indexFilterSet": false, "parsedQuery": { "nums.0": { "$exists": true } }, "winningPlan": { "stage": "COLLSCAN", "filter": { "nums.0": { "$exists": true } }, "direction": "forward" }, "rejectedPlans": [ ] }, "serverInfo": { "host": "MacBook-Pro", "port": 27017, "version": "3.0.14", "gitVersion": "08352afcca24bfc145240a0fac9d28b978ab77f3" }, "ok": 1 }
--
db.doc.find ({ 'nums가'{$가 존재 : 사실, $있다 : { '$ 크기': 0}}}) 잘못된 결과를 반환합니다. 때문에 잘못된 인덱스의의는 어떤 문서를 진행하지 스캔합니다. 그것은 가능성이 정확하지만, 인덱스없이 속도가 느려집니다.
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $gt: { '$size': 0 }}}).count() 0 MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $gt: { '$size': 0 }}}).explain('executionStats').executionStats.executionStages { "stage": "KEEP_MUTATIONS", "nReturned": 0, "executionTimeMillisEstimate": 0, "works": 2, "advanced": 0, "needTime": 0, "needFetch": 0, "saveState": 0, "restoreState": 0, "isEOF": 1, "invalidates": 0, "inputStage": { "stage": "FETCH", "filter": { "$and": [ { "nums": { "$gt": { "$size": 0 } } }, { "nums": { "$exists": true } } ] }, "nReturned": 0, "executionTimeMillisEstimate": 0, "works": 1, "advanced": 0, "needTime": 0, "needFetch": 0, "saveState": 0, "restoreState": 0, "isEOF": 1, "invalidates": 0, "docsExamined": 0, "alreadyHasObj": 0, "inputStage": { "stage": "IXSCAN", "nReturned": 0, "executionTimeMillisEstimate": 0, "works": 1, "advanced": 0, "needTime": 0, "needFetch": 0, "saveState": 0, "restoreState": 0, "isEOF": 1, "invalidates": 0, "keyPattern": { "nums": 1 }, "indexName": "nums_1", "isMultiKey": true, "direction": "forward", "indexBounds": { "nums": [ "({ $size: 0.0 }, [])" ] }, "keysExamined": 0, "dupsTested": 0, "dupsDropped": 0, "seenInvalidated": 0, "matchTested": 0 } } }
--
db.doc.find ({ 'nums가'{$가 존재 : 사실, $ 없습니다 : { '$ 크기': 0}}}) 올바른 결과를 반환하지만 성능이 좋지 않습니다. 그것은 기술적으로 인덱스 스캔을 수행,하지만 여전히 모든 문서를 전진하고) 그들을 통해 필터에있다.
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $not: { '$size': 0 }}}).count() 5 MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $not: { '$size': 0 }}}).explain('executionStats').executionStats.executionStages { "stage": "KEEP_MUTATIONS", "nReturned": 5, "executionTimeMillisEstimate": 0, "works": 2016, "advanced": 5, "needTime": 2010, "needFetch": 0, "saveState": 15, "restoreState": 15, "isEOF": 1, "invalidates": 0, "inputStage": { "stage": "FETCH", "filter": { "$and": [ { "nums": { "$exists": true } }, { "$not": { "nums": { "$size": 0 } } } ] }, "nReturned": 5, "executionTimeMillisEstimate": 0, "works": 2016, "advanced": 5, "needTime": 2010, "needFetch": 0, "saveState": 15, "restoreState": 15, "isEOF": 1, "invalidates": 0, "docsExamined": 2005, "alreadyHasObj": 0, "inputStage": { "stage": "IXSCAN", "nReturned": 2005, "executionTimeMillisEstimate": 0, "works": 2015, "advanced": 2005, "needTime": 10, "needFetch": 0, "saveState": 15, "restoreState": 15, "isEOF": 1, "invalidates": 0, "keyPattern": { "nums": 1 }, "indexName": "nums_1", "isMultiKey": true, "direction": "forward", "indexBounds": { "nums": [ "[MinKey, MaxKey]" ] }, "keysExamined": 2015, "dupsTested": 2015, "dupsDropped": 10, "seenInvalidated": 0, "matchTested": 0 } } }
--
db.doc.find ({ 'nums가'{$가 존재 : 사실, $ NE는 : []}}) 올바른 결과를 반환하고 약간 빠르지 만 성능은 아직 적합하지 않습니다. 그것은 단지 기존의 목록 필드에 문서를 전진 IXSCAN를 사용하지만, 다음 빈 목록 하나 하나를 필터링 할 수 있습니다.
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $ne: [] }}).count() 5 MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $ne: [] }}).explain('executionStats').executionStats.executionStages { "stage": "KEEP_MUTATIONS", "nReturned": 5, "executionTimeMillisEstimate": 0, "works": 1018, "advanced": 5, "needTime": 1011, "needFetch": 0, "saveState": 15, "restoreState": 15, "isEOF": 1, "invalidates": 0, "inputStage": { "stage": "FETCH", "filter": { "$and": [ { "$not": { "nums": { "$eq": [ ] } } }, { "nums": { "$exists": true } } ] }, "nReturned": 5, "executionTimeMillisEstimate": 0, "works": 1017, "advanced": 5, "needTime": 1011, "needFetch": 0, "saveState": 15, "restoreState": 15, "isEOF": 1, "invalidates": 0, "docsExamined": 1005, "alreadyHasObj": 0, "inputStage": { "stage": "IXSCAN", "nReturned": 1005, "executionTimeMillisEstimate": 0, "works": 1016, "advanced": 1005, "needTime": 11, "needFetch": 0, "saveState": 15, "restoreState": 15, "isEOF": 1, "invalidates": 0, "keyPattern": { "nums": 1 }, "indexName": "nums_1", "isMultiKey": true, "direction": "forward", "indexBounds": { "nums": [ "[MinKey, undefined)", "(undefined, [])", "([], MaxKey]" ] }, "keysExamined": 1016, "dupsTested": 1015, "dupsDropped": 10, "seenInvalidated": 0, "matchTested": 0 } } }
--
db.doc.find ({ 'nums'$ {GT를 []}})의 INDEX는 IT 예기치 않은 결과를 줄 수도 USED DEPENDING 위험한 때문이다. 그 때문에 어떤 문서를 전진하지 잘못된 인덱스 스캔의입니다.
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: [] }}).count() 0 MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: [] }}).hint({ nums: 1 }).count() 0 MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: [] }}).hint({ _id: 1 }).count() 5 MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: [] }}).explain('executionStats').executionStats.executionStages { "stage": "KEEP_MUTATIONS", "nReturned": 0, "executionTimeMillisEstimate": 0, "works": 1, "advanced": 0, "needTime": 0, "needFetch": 0, "saveState": 0, "restoreState": 0, "isEOF": 1, "invalidates": 0, "inputStage": { "stage": "FETCH", "filter": { "nums": { "$gt": [ ] } }, "nReturned": 0, "executionTimeMillisEstimate": 0, "works": 1, "advanced": 0, "needTime": 0, "needFetch": 0, "saveState": 0, "restoreState": 0, "isEOF": 1, "invalidates": 0, "docsExamined": 0, "alreadyHasObj": 0, "inputStage": { "stage": "IXSCAN", "nReturned": 0, "executionTimeMillisEstimate": 0, "works": 1, "advanced": 0, "needTime": 0, "needFetch": 0, "saveState": 0, "restoreState": 0, "isEOF": 1, "invalidates": 0, "keyPattern": { "nums": 1 }, "indexName": "nums_1", "isMultiKey": true, "direction": "forward", "indexBounds": { "nums": [ "([], BinData(0, ))" ] }, "keysExamined": 0, "dupsTested": 0, "dupsDropped": 0, "seenInvalidated": 0, "matchTested": 0 } } }
--
db.doc.find ({ 'nums.0': {$있다 : -Infinity는}}) 올바른 결과를 반환하지만 나쁜 성능 (전체 수집 스캔을 사용)이있다.
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums.0': { $gt: -Infinity }}).count() 5 MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums.0': { $gt: -Infinity }}).explain('executionStats').executionStats.executionStages { "stage": "COLLSCAN", "filter": { "nums.0": { "$gt": -Infinity } }, "nReturned": 5, "executionTimeMillisEstimate": 0, "works": 2007, "advanced": 5, "needTime": 2001, "needFetch": 0, "saveState": 15, "restoreState": 15, "isEOF": 1, "invalidates": 0, "direction": "forward", "docsExamined": 2005 }
--
db.doc.find ({ 'nums은'{$있다 : -Infinity는}}) 놀랍게도, 이것은 매우 잘 작동합니다! 그것은 바로 결과를 제공하며 인덱스 스캔 단계에서 5 문서를 전진, 빨리.
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: -Infinity }}).explain('executionStats').executionStats.executionStages { "stage": "FETCH", "nReturned": 5, "executionTimeMillisEstimate": 0, "works": 16, "advanced": 5, "needTime": 10, "needFetch": 0, "saveState": 0, "restoreState": 0, "isEOF": 1, "invalidates": 0, "docsExamined": 5, "alreadyHasObj": 0, "inputStage": { "stage": "IXSCAN", "nReturned": 5, "executionTimeMillisEstimate": 0, "works": 15, "advanced": 5, "needTime": 10, "needFetch": 0, "saveState": 0, "restoreState": 0, "isEOF": 1, "invalidates": 0, "keyPattern": { "nums": 1 }, "indexName": "nums_1", "isMultiKey": true, "direction": "forward", "indexBounds": { "nums": [ "(-inf.0, inf.0]" ] }, "keysExamined": 15, "dupsTested": 15, "dupsDropped": 10, "seenInvalidated": 0, "matchTested": 0 } }
-
==============================
5.2.6 릴리스부터이 작업을 수행하는 또 다른 방법은 빈 배열에 필드를 비교하는 것입니다 :
2.6 릴리스부터이 작업을 수행하는 또 다른 방법은 빈 배열에 필드를 비교하는 것입니다 :
ME.find({pictures: {$gt: []}})
쉘에서 그것을 테스트 :
> db.ME.insert([ {pictures: [1,2,3]}, {pictures: []}, {pictures: ['']}, {pictures: [0]}, {pictures: 1}, {foobar: 1} ]) > db.ME.find({pictures: {$gt: []}}) { "_id": ObjectId("54d4d9ff96340090b6c1c4a7"), "pictures": [ 1, 2, 3 ] } { "_id": ObjectId("54d4d9ff96340090b6c1c4a9"), "pictures": [ "" ] } { "_id": ObjectId("54d4d9ff96340090b6c1c4aa"), "pictures": [ 0 ] }
사진 적어도 하나 개의 배열 요소를 가지고 있으며, 제외 사진 중 하나는 하늘의 배열이 아니라 배열 또는 누락 된 워드 프로세서를 어디 제대로 문서를 포함 그래서.
-
==============================
6.이 작업을 달성하기 위해 다음 중 하나를 사용할 수 있습니다. 둘 다 또한 그들의 요청 키가없는 개체에 대한 결과를 반환하지 돌봐 :
이 작업을 달성하기 위해 다음 중 하나를 사용할 수 있습니다. 둘 다 또한 그들의 요청 키가없는 개체에 대한 결과를 반환하지 돌봐 :
db.video.find({pictures: {$exists: true, $gt: {$size: 0}}}) db.video.find({comments: {$exists: true, $not: {$size: 0}}})
-
==============================
7.
{ $where: "this.pictures.length > 1" }
$ 어디에 사용할 배열 필드의 크기를 반환 this.field_name.length를 통과 수에 비교하여 확인한다. 임의의 어레이가 배열 크기보다 가치가있는 경우 배열 필드 길이보다 하나가 매우 모두 그것이 그 어레이의 일부 데이터를 의미하며, 적어도 1이어야
-
==============================
8.
ME.find({pictures: {$type: 'array', $ne: []}})
대신 $ 유형의 4 : 4 : '배열'이전 3.2에 MongoDB의 버전을 사용하는 경우, $ 유형을 사용합니다. 이 솔루션도 $ 크기를 사용하지 않도록주의 때문에 인덱스 문제 ( "쿼리는 쿼리의 $ 크기 부분에 대한 인덱스를 사용할 수 없습니다")가 없다
이 (허용 대답)를 포함하여 다른 솔루션 :
그들은 예를 들어, 문서의 경우에도를 반환하기 때문에 잘못, '사진'널 (null), 정의되지 않은, 0 등입니다
-
==============================
9.$ elemMatch 연산자를 사용하여 문서에 따라
$ elemMatch 연산자를 사용하여 문서에 따라
$ elemMatches는 값이 배열인지 확인하게하고 비어 있지 않은지. 쿼리는 같은 것이다 그래서
ME.find ({사진 : {$ elemMatch : {$가 존재 : TRUE}}})
이 코드의 추신 변형은 MongoDB를 대학의 M121 과정에서 발견된다.
-
==============================
10.또한 몽고 연산자 $가 존재하는 도우미 메서드가 이상 존재 사용할 수 있습니다
또한 몽고 연산자 $가 존재하는 도우미 메서드가 이상 존재 사용할 수 있습니다
ME.find() .exists('pictures') .where('pictures').ne([]) .sort('-created') .limit(10) .exec(function(err, results){ ... });
-
==============================
11.
ME.find({pictures: {$exists: true}})
간단한 것과,이 날 위해 일했습니다.
from https://stackoverflow.com/questions/14789684/find-mongodb-records-where-array-field-is-not-empty by cc-by-sa and MIT license
'MONGODB' 카테고리의 다른 글
[MONGODB] 어떤 수준에 쓰기에 MongoDB를 잠금을합니까? (나 : 그것은 "연결 당"에 의해 무엇을 의미 하는가 (0) | 2019.12.05 |
---|---|
[MONGODB] MongoDB의 데이터 저장소 디렉토리를 변경 (0) | 2019.12.05 |
[MONGODB] 어떻게 MongoDB를 함께 Elasticsearch를 사용 하는가? (0) | 2019.12.05 |
[MONGODB] 산드 대 MongoDB를 [폐쇄] (0) | 2019.12.05 |
[MONGODB] 처리되지 않은 약속을 거부 : 오류 : URL을 구문 분석 할 수 없습니다, 부정 (0) | 2019.12.04 |