복붙노트

[MONGODB] 분야별 MongoDB를 집계가 존재

MONGODB

분야별 MongoDB를 집계가 존재

이 질문은 질문 어딘가에 이미 대답하지 않은 믿기 힘든 시간을 가지고,하지만 난 그것의 흔적을 찾을 수 없습니다.

나는 MongoDB를 집계 쿼리를 부울로 그룹에 요구한다 : 다른 필드의 존재.

예를 들어의이 컬렉션을 시작하자 :

> db.test.find()
{ "_id" : ObjectId("53fbede62827b89e4f86c12e"),
  "field" : ObjectId("53fbede62827b89e4f86c12d"), "name" : "Erik" }
{ "_id" : ObjectId("53fbee002827b89e4f86c12f"), "name" : "Erik" }
{ "_id" : ObjectId("53fbee092827b89e4f86c131"),
  "field" : ObjectId("53fbee092827b89e4f86c130"), "name" : "John" }
{ "_id" : ObjectId("53fbee122827b89e4f86c132"), "name" : "Ben" }

이 문서는 "필드"를 가지고 있고, (2)는하지 않습니다. "필드"의 각 값이 상이 할 수 있음에 유의 우리는 단지 (I 저장에 null 값이없는, 너무 나를 위해 또는 비 nullness 작품)의 존재에 그룹으로합니다.

나는 $ 프로젝트를 사용하여 시도했지만, $가 존재하지 않는 존재하고 $ 콘드과 $는 나에게 도움이되지 않은 IFNULL. 필드는 항상 그렇지 않은 경우에도 존재하는 것으로 나타납니다 :

> db.test.aggregate(
  {$project:{fieldExists:{$cond:[{$eq:["$field", null]}, false, true]}}},
  {$group:{_id:"$fieldExists", count:{$sum:1}}}
)
{ "_id" : true, "count" : 4 }

나는 일을 다음과 같이 훨씬 간단 집계를 기대하지만, 어떤 이유로 $ 이런 식으로 지원되지 않습니다 존재 :

> db.test.aggregate({$group:{_id:{$exists:"$field"}, count:{$sum:1}}})
assert: command failed: {
  "errmsg" : "exception: invalid operator '$exists'",
  "code" : 15999,
  "ok" : 0
} : aggregate failed
Error: command failed: {
  "errmsg" : "exception: invalid operator '$exists'",
  "code" : 15999,
  "ok" : 0
} : aggregate failed
    at Error (<anonymous>)
    at doassert (src/mongo/shell/assert.js:11:14)
    at Function.assert.commandWorked (src/mongo/shell/assert.js:244:5)
    at DBCollection.aggregate (src/mongo/shell/collection.js:1149:12)
    at (shell):1:9
2014-08-25T19:19:42.344-0700 Error: command failed: {
  "errmsg" : "exception: invalid operator '$exists'",
  "code" : 15999,
  "ok" : 0
} : aggregate failed at src/mongo/shell/assert.js:13

사람이 같은 모음에서 원하는 결과를 얻는 방법을 알고 있나요?

예상 결과:

{ "_id" : true, "count" : 2 }
{ "_id" : false, "count" : 2 }

해결법

  1. ==============================

    1.나는 어젯밤 이런 식으로 같은 문제를 해결 :

    나는 어젯밤 이런 식으로 같은 문제를 해결 :

    > db.test.aggregate({$group:{_id:{$gt:["$field", null]}, count:{$sum:1}}})
    { "_id" : true, "count" : 2 }
    { "_id" : false, "count" : 2 }
    

    이것이 어떻게 작동하는지에 대한 자세한 설명은 http://docs.mongodb.org/manual/reference/bson-types/#bson-types-comparison-order를 참조하십시오.

  2. ==============================

    2.나는 정의되지 않은 검사로 해결

    나는 정의되지 않은 검사로 해결

    $ne : [$var_to_check, undefined]
    

    또는

    $ne:  [ { $type : "$var_to_check"}, 'missing'] }
    

    var에 정의 된 경우이 사실 반환

  3. ==============================

    3.$ 그것이 "필터"결과를 기본적으로 사용하기보다는 논리적 인 조건을 식별되도록 운영자가하는 "쿼리"연산자 존재한다.

    $ 그것이 "필터"결과를 기본적으로 사용하기보다는 논리적 인 조건을 식별되도록 운영자가하는 "쿼리"연산자 존재한다.

    는 "논리적"연산자로 집계 프레임 워크는 $ IFNULL 연산자를 지원합니다. 존재하는이 반환 필드 값하거나하지 않거나 그렇지 않습니다 대체 제공된 값은 널 (null)로 평가

    db.test.aggregate([
        { "$group": {
            "_id": { "$ifNull": [ "$field", false ] },
            "count": { "$sum": 1 }
        }}
    ])
    

    그러나 물론, 심지어 존재하는 곳 당신이 실제로 당신은 당신이 훨씬처럼 아마 더 나은 $ 콘드 문 꺼져있는 필드의 실제 값을 반환하려면 그렇게하지 않는 한 "참 / 거짓"비교하지입니다 :

    db.test.aggregate([
        { "$group": {
            "_id": { "$cond": [{ "$eq": [ "$field", null ] }, true, false ] },
            "count": { "$sum": 1 }
        }}
    ])
    

    어디 $ IFNULL이 매우 유용 할 수 있습니다하면 오류가 $ 언 와인드 프로그램을 사용하는 것과 달리이 발생하지 존재 배열 필드를 교체입니다. 이 파이프 라인 처리의 나머지 부분에서 문제가 발생하지 않도록 단일 요소 또는 빈 배열을 반환처럼 그런 일을 할 수 있습니다.

  4. ==============================

    4.몰라는했지만 지금은 2019 깨끗한 솔루션은이 방법에 대해 설명합니다. 통합 파이프 라인에서이 작업을 수행

    몰라는했지만 지금은 2019 깨끗한 솔루션은이 방법에 대해 설명합니다. 통합 파이프 라인에서이 작업을 수행

    $match: {"my_field": {$ne: null}}
    

    좋은 점은 내 랭 'NE'는하지에 :)

  5. ==============================

    5.내 대답은 :

    내 대답은 :

    {'$project': {
        'field_exists': {'$or': [
            {'$eq': ['$field', null]}, 
            {'$gt': ['$field', null]},
        ]},
    }}
    

    여기에 세부 사항입니다. $는 null 또는 다른 빈 값이있는 경우에도, 필드가 존재한다는 것을 의미 존재한다. 이 페이지에 모든 해답이 잘못된 이유입니다.

    하자 검사 조금. 이 옵션을 선택합니다 :

    // Let's take any collection that have docs
    db.getCollection('collection').aggregate([
      // Get arbitrary doc, no matter which, we won't use it
      {"$limit": 1},
      // Project our own fields (just create them with $literal)
      {'$project': {
        '_id': 0,
        'null_field': {'$literal': null},
        'not_null_field': {'$literal': {}},
      }},
    ])
    

    우리는이를 얻을 수 있습니다 :

    {
        "null_field" : null,
        "not_null_field" : {}
    }
    

    그럼이 문서에 존재하는 필드를 명확히하자 :

    좋아, 내가 위에서 언급 한 테스트 프로젝트 단계에 시간이다. 의 우리가 관심있는 모든 필드를 추가 할 수 있습니다 :

    {'$project': {
        'null_field_exists': {'$or': [
            {'$eq': ['$null_field', null]}, 
            {'$gt': ['$null_field', null]},
        ]},
        'not_null_field_exists': {'$or': [
            {'$eq': ['$not_null_field', null]}, 
            {'$gt': ['$not_null_field', null]},
        ]},
        'non_existent_field_exists': {'$or': [
            {'$eq': ['$non_existent_field', null]}, 
            {'$gt': ['$non_existent_field', null]},
        ]},
    }},
    

    우리가 얻을 것은 :

    {
        "null_field_exists" : true,
        "not_null_field_exists" : true,
        "non_existent_field_exists" : false
    }
    

    옳은!

    그리고 작은 참고 : 그것은 (작은 단지가 아닌 존재입니다) 적어도 가치가 가장 작은 값이기 때문에 우리는 비교에 null를 사용합니다.

  6. from https://stackoverflow.com/questions/25497150/mongodb-aggregate-by-field-exists by cc-by-sa and MIT license