[MONGODB] 키 필드에 의해 MongoDB의 컬렉션에서 모든 중복 문서를 찾기
MONGODB키 필드에 의해 MongoDB의 컬렉션에서 모든 중복 문서를 찾기
나는 문서의 일부 세트 컬렉션을 가지고 가정하자. 이 같은.
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":1, "name" : "foo"}
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":2, "name" : "bar"}
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":3, "name" : "baz"}
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":4, "name" : "foo"}
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":5, "name" : "bar"}
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":6, "name" : "bar"}
나는 "이름"필드에 의해이 컬렉션의 모든 중복 항목을 찾고 싶어요. 예를 들면 "푸"두 번 표시하고 "바"3 번 나타납니다.
해결법
-
==============================
1.참고 :이 솔루션은 이해하기 쉬운, 그러나 최고입니다.
참고 :이 솔루션은 이해하기 쉬운, 그러나 최고입니다.
당신은 문서가 특정 필드가 몇 번 찾아 맵리 듀스를 사용할 수 있습니다 :
var map = function(){ if(this.name) { emit(this.name, 1); } } var reduce = function(key, values){ return Array.sum(values); } var res = db.collection.mapReduce(map, reduce, {out:{ inline : 1}}); db[res.result].find({value: {$gt: 1}}).sort({value: -1});
-
==============================
2.허용 대답은 대형 컬렉션에 정말 느린이며, 중복 레코드의 _ids를 반환하지 않습니다.
허용 대답은 대형 컬렉션에 정말 느린이며, 중복 레코드의 _ids를 반환하지 않습니다.
집계는 훨씬 더 빨리하고 _ids을 반환 할 수 있습니다 :
db.collection.aggregate([ { $group: { _id: { name: "$name" }, // replace `name` here twice uniqueIds: { $addToSet: "$_id" }, count: { $sum: 1 } } }, { $match: { count: { $gte: 2 } } }, { $sort : { count : -1} }, { $limit : 10 } ]);
집계 파이프 라인의 첫 번째 단계에서, $ 그룹 uniqueIds 연산자 집합체의 이름 필드가 문서 저장 그룹화 된 각 레코드 _id 값. 하여 $ 합 조작이 경우, 일정한 1 전달 된 필드의 값을 가산 - 이에 카운트 필드로 분류 레코드의 개수를 카운트.
파이프 라인의 두 번째 단계에서, 우리는 $ 일치를 사용 적어도 2의 카운트, 즉 중복 필터와 문서.
그런 다음 우리는 종류의 가장 흔한 첫 번째 중복, 그리고 상위 10에 결과를 제한 할 수 있습니다.
자신의 _ids과 함께 중복 된 이름을 가진 $ 한계 기록이 쿼리가 출력해서. 예를 들면 :
{ "_id" : { "name" : "Toothpick" }, "uniqueIds" : [ "xzuzJd2qatfJCSvkN", "9bpewBsKbrGBQexv4", "fi3Gscg9M64BQdArv", ], "count" : 3 }, { "_id" : { "name" : "Broom" }, "uniqueIds" : [ "3vwny3YEj2qBsmmhA", "gJeWGcuX6Wk69oFYD" ], "count" : 2 }
-
==============================
3.일반적인 몽고 솔루션의 경우, 그룹을 사용하여 중복을 찾기위한 MongoDB의 요리 책의 레시피를 참조하십시오. 이 집계는보다 빠르고 강력한에서는 중복 레코드의 _ids를 반환 할 수 있다는 것입니다 있습니다.
일반적인 몽고 솔루션의 경우, 그룹을 사용하여 중복을 찾기위한 MongoDB의 요리 책의 레시피를 참조하십시오. 이 집계는보다 빠르고 강력한에서는 중복 레코드의 _ids를 반환 할 수 있다는 것입니다 있습니다.
pymongo의 경우, 허용 대답은 (맵리 듀스를 사용하여)이 효율적이지 않습니다. 대신, 우리는 그룹 방법을 사용할 수 있습니다 :
$connection = 'mongodb://localhost:27017'; $con = new Mongo($connection); // mongo db connection $db = $con->test; // database $collection = $db->prb; // table $keys = array("name" => 1); Select name field, group by it // set intial values $initial = array("count" => 0); // JavaScript function to perform $reduce = "function (obj, prev) { prev.count++; }"; $g = $collection->group($keys, $initial, $reduce); echo "<pre>"; print_r($g);
출력이 될 것입니다 :
Array ( [retval] => Array ( [0] => Array ( [name] => [count] => 1 ) [1] => Array ( [name] => MongoDB [count] => 2 ) ) [count] => 3 [keys] => 2 [ok] => 1 )
동등한 SQL 쿼리는 다음과 같습니다 이름으로 PRB 그룹에서 SELECT 이름, COUNT (이름). 우리는 여전히 배열에서 0의 수와 요소를 필터링 할 필요가 있습니다. 다시 말하지만, 그룹을 사용하여 표준 솔루션 그룹을 사용하여 중복을 찾기위한 MongoDB의 요리 책 레시피를 참조하십시오.
-
==============================
4.나는 공식 몽고 랩 블로그에 유용한 정보를 발견 : http://blog.mongolab.com/2014/03/finding-duplicate-keys-with-the-mongodb-aggregation-framework/
나는 공식 몽고 랩 블로그에 유용한 정보를 발견 : http://blog.mongolab.com/2014/03/finding-duplicate-keys-with-the-mongodb-aggregation-framework/
-
==============================
5.여기에 가장 높은 허용 대답이있다 :
여기에 가장 높은 허용 대답이있다 :
uniqueIds: { $addToSet: "$_id" },
그것은 또한 ID의 목록을 당신에게 uniqueIds라는 새 필드를 반환합니다. 하지만 당신은 단지 필드의 수를 어떻게해야할까요? 그 다음이 될 것입니다 :
db.collection.aggregate([ {$group: { _id: {name: "$name"}, count: {$sum: 1} } }, {$match: { count: {"$gt": 1} } } ]);
당신은 MySQL과 PostgreSQL을 같은 SQL 데이터베이스에서 오는 경우이를 설명하기 위해, 당신은 집계 함수에 익숙한 (예를 들어, COUNT (), SUM (), MIN (), MAX는 ()) 문 BY 그룹과 함께하는 일을 위해, 당신을 허용 예를 들어, 열 값은 표에 나타나는 총 카운트를 검색한다.
SELECT COUNT(*), my_type FROM table GROUP BY my_type; +----------+-----------------+ | COUNT(*) | my_type | +----------+-----------------+ | 3 | Contact | | 1 | Practice | | 1 | Prospect | | 1 | Task | +----------+-----------------+
당신이 볼 수 있듯이, 우리의 출력을 보여줍니다 카운트 각 my_type 값이 나타납니다. MongoDB의 중복 항목을 찾으려면, 우리는 유사한 방법으로 문제를 해결한다. MongoDB를 자랑은 복수의 문서로부터 연산 그룹 값을 집계하고 단일 결과를 반환하기 위해 그룹화 된 데이터에 다양한 작업을 수행 할 수있다. 그것은 SQL의 집계 함수와 유사한 개념이다.
모음라는 연락처, 다음과 같이 초기 설정 외모를 가정 :
db.contacts.aggregate([ ... ]);
이 집계 함수는 집계 사업자의 배열을, 우리의 목표는 필드의 수, 필드 값의 차례 나오는 수만큼 데이터가 그룹이기 때문에 우리의 경우, 우리는 $ 그룹 연산자를 원한다.
db.contacts.aggregate([ {$group: { _id: {name: "$name"} } } ]);
이 방법에 약간의 idiosyncracy이있다. _id 필드는 오퍼레이터에 의해 그룹을 사용하는 것이 요구된다. 이 경우, 우리는 $ 이름 필드를 그룹화하고 있습니다. _id 내에서 키 이름은 어떤 이름을 가질 수 있습니다. 그것은 여기에 직관적이기 때문에 그러나 우리는 이름을 사용합니다.
(가 컬렉션에 한 번 이상 한 번 이상 나타나면 관계없이)에만 $ 그룹 연산자를 사용하여 집계를 실행하여, 우리는 이름 필드의 목록을 얻을 것이다 :
db.contacts.aggregate([ {$group: { _id: {name: "$name"} } } ]); { "_id" : { "name" : "John" } } { "_id" : { "name" : "Joan" } } { "_id" : { "name" : "Stephen" } } { "_id" : { "name" : "Rod" } } { "_id" : { "name" : "Albert" } } { "_id" : { "name" : "Amanda" } }
집계가 어떻게 작동하는지 위의주의 사항. 그것은 이름 필드 문서를했다 추출 이름 필드의 새 컬렉션을 반환합니다.
하지만 우리가 알고 싶은 것은 많은 시간이 필드 값 다시 표시하지 방법이다. 하여 $ 그룹 운영자는 그룹 내의 각 문서의 총 식 1을 추가 $ 합 연산자를 사용하여 카운트 필드 걸린다. 는 $ 그룹 그래서 및 $ 합 함께 모든 숫자 값의 집단 합계를 반환 주어진 필드 (예 : 이름)에 대한 결과입니다.
db.contacts.aggregate([ {$group: { _id: {name: "$name"}, count: {$sum: 1} } } ]); { "_id" : { "name" : "John" }, "count" : 1 } { "_id" : { "name" : "Joan" }, "count" : 3 } { "_id" : { "name" : "Stephen" }, "count" : 2 } { "_id" : { "name" : "Rod" }, "count" : 3 } { "_id" : { "name" : "Albert" }, "count" : 2 } { "_id" : { "name" : "Amanda" }, "count" : 1 }
목표는 중복을 제거하는 것이었다 때문에, 하나의 추가 단계가 필요합니다. 하나 이상의 수를에만 그룹을 얻으려면, 우리는 우리의 결과를 필터링 할 $ 일치 연산자를 사용할 수 있습니다. 은 $ 일치 연산자 내에서, 우리는 카운트 필드를 확인하고 "이상"과 숫자 1을 나타내는 $ GT는 연산자를 사용하여 하나 이상의 계수를 찾기 위해 그에게 그것을 말할 것이다.
db.contacts.aggregate([ {$group: { _id: {name: "$name"}, count: {$sum: 1} } }, {$match: { count: {"$gt": 1} } } ]); { "_id" : { "name" : "Joan" }, "count" : 3 } { "_id" : { "name" : "Stephen" }, "count" : 2 } { "_id" : { "name" : "Rod" }, "count" : 3 } { "_id" : { "name" : "Albert" }, "count" : 2 }
루비에 대한 Mongoid 같은 ORM을 통해 MongoDB를 사용하는 경우 보조 노트로서,이 오류를 얻을 수 있습니다 :
The 'cursor' option is required, except for aggregate with the explain argument
이 가능성이 가장 높은 수단 당신의 ORM은 오래되어 그 MongoDB를 더 이상 지원하지 않는 작업을 수행하고 있습니다. 따라서, 중 당신의 ORM을 업데이트하거나 수정 프로그램을 찾을 수 있습니다. Mongoid, 이것은 나를 위해 수정했다 :
module Moped class Collection # Mongo 3.6 requires a `cursor` option be passed as part of aggregate queries. This overrides # `Moped::Collection#aggregate` to include a cursor, which is not provided by Moped otherwise. # # Per the [MongoDB documentation](https://docs.mongodb.com/manual/reference/command/aggregate/): # # Changed in version 3.6: MongoDB 3.6 removes the use of `aggregate` command *without* the `cursor` option unless # the command includes the `explain` option. Unless you include the `explain` option, you must specify the # `cursor` option. # # To indicate a cursor with the default batch size, specify `cursor: {}`. # # To indicate a cursor with a non-default batch size, use `cursor: { batchSize: <num> }`. # def aggregate(*pipeline) # Ordering of keys apparently matters to Mongo -- `aggregate` has to come before `cursor` here. extract_result(session.command(aggregate: name, pipeline: pipeline.flatten, cursor: {})) end private def extract_result(response) response.key?("cursor") ? response["cursor"]["firstBatch"] : response["result"] end end end
from https://stackoverflow.com/questions/9491920/find-all-duplicate-documents-in-a-mongodb-collection-by-a-key-field by cc-by-sa and MIT license
'MONGODB' 카테고리의 다른 글
[MONGODB] 그것은 MongoDB를위한 RAM에 "작업 집합"에 맞게 무엇을 의미 하는가? (0) | 2019.12.09 |
---|---|
[MONGODB] 때 Nodejs에서 MongoDB를 데이터베이스 연결을 닫습니다 (0) | 2019.12.09 |
[MONGODB] 몽구스 - 포스 콜렉션 이름 (0) | 2019.12.09 |
[MONGODB] 동일한 데이터베이스 내에서 컬렉션을 복사하는 가장 빠른 방법은 무엇입니까? (0) | 2019.12.09 |
[MONGODB] 인덱싱 된 열에 선택 MongoDB를 카운트 (고유 X) - 대용량 데이터 세트에 대한 고유 결과를 집계 (0) | 2019.12.09 |