2017-12-16 16 views
0

나는 풀의 모든 요소를 ​​검색하여 "풀"의 모든 문서를 반환하도록하는 프로젝트에서 작업하고 있습니다. 예를 들면 그래서해당 요소 중 하나라도 쿼리 할 수있는 문서를 만드는 올바른 방법은 무엇입니까?

우리가 3 개 풀을 가지고 말할 수, 편지

에 의해 표시 다양한 문서와 각

수영장 1 : A, B, C

수영장 2 : D

수영장 3 : E, F, G, H

A을 검색하고 A, BC을 얻고 싶습니다. C을 검색 할 때 A, BC을 받고 싶습니다.

I 문서를 추가하고 풀 1과 2에 대한 기준을 충족하면 풀 1과 풀 2를 병합해야하며 A, B, C, D, I을 검색하면 모든 결과가 반환되어야합니다.

이 작업을 비효율적으로 수행하는 방법을 알고 있습니다. 각 요소가 키로 된 새 문서를 만든 다음 각 삽입시 모든 문서를 업데이트합니다. 그러나 더 좋은 방법이 있는지 궁금합니다.

미리 감사

+0

[색인] (https://docs.mongodb.com/manual/indexes/)을 보았습니까? – displayName

+0

키를 보는 대신 문서의 요소를보기 위해 쿼리를 다시 작성하는 방법을 생각해보십시오. – displayName

+0

또는 문서/컬렉션 * 디자인 *을 수정하면 쉽게 쿼리 할 수 ​​있습니다. – displayName

답변

1

에 나는 데이터, 특히 데이터베이스 문서로 추상적 뭔가 좋은 시각화 문제를 개념화 할 수 있다고 생각합니다. 깊이 1의 트리 집합을 유지하려고 시도하는 관점에서이 문제를 살펴보십시오. 특히 각 문서는 리프이고 어떤 문서가 "풀"의 일부인지 판단하는 "규칙"은 루트입니다 (예 : 루트는 리프가 될 수있는 레이블의 서브 세트입니다).

자, 이제 새 잎을 추가 할 수 있습니다. 이 리프가 둘 이상의 루트에 연결될 수 있으면 해당 루트를 병합해야합니다. 즉 루트가 무엇인지 업데이트하고 영향을받은 트리의 모든 리프를이 새로운 루트로 지정해야합니다.

그렇지 않으면 결국 새 잎에서 연결되는 뿌리까지 그리고 다른 모든 잎으로 뛰어 넘을 필요가 있습니다. 그러나 서로 다른 잎은 잠재적으로 다른 뿌리에도 연결될 수 있습니다. 즉,이 임의의 횟수만큼 뛰어 넘을 수 있습니다. 이는 이상적이지 않은 상황입니다.

이 쿼리를 효율적으로 수행하려면 이러한 "루트"가 무엇인지 결정하고 그에 따라 업데이트해야합니다. 예를 들어, "풀"문서를 유지하고 필요에 따라 이러한 "풀"을 병합하기로 결정할 수 있습니다. 풀에 포함될 레이블 배열 인 labels 필드가 있습니다. 병합은 배열 자체를 병합하는 것입니다. 또는 공통 ObjectId (특정 문서에 반드시 첨부 할 필요는 없음)를 사용할 수 있으며이 값을 문서가있는 대신 "유사 루트 노드"의 일종으로 사용할 수 있습니다. 탐색 할 수있는 다양한 옵션이 있습니다. 그러나 일반적으로 개별 문서의 입력란 검사를 단일 값 확인으로 줄이기 위해 노력해야합니다 (예 : 각 문서에서 다른 "관련"라벨의 배열을 유지하지 마십시오).

접근 방법에 관계없이 이러한 트리 구조를 염두에두고 MongoDB 쿼리와 관련하여 노드를 통과한다는 의미를 고려하고 노드를 트래버스하려는 방법을 결정하여 1) 홉 (Hops) "은 상수 시간 작업이므로 2) 데이터 손실 위험없이 효율적으로 안정적으로 해당 루트를 병합 할 수 있는지 확인하십시오.

마지막으로 업데이트 쿼리가 너무 느리다면 인덱싱 문제가 발생할 가능성이 큽니다. 적절한 색인을 사용하면 수백만 개의 문서가 포함 된 모음집을 업데이트하는 데 시간이 전혀 걸리지 않습니다. 또한 multi 업데이트를 수행하지 않고 각 문서에 대해 개별 업데이트를 실행하는 경우 검색 시간과 네트워크 오버 헤드가 O(n)이되어 업데이트가 잘못 작성되므로 업데이트가 잘못 작성됩니다. 포복.