2017-12-16 15 views
0

私は、プール内のすべての要素を検索して「プール」内のすべてのドキュメントを返すプロジェクトに取り組んでいます。例えばのでその要素のいずれかによって照会できる文書を作成する正しい方法は何ですか?

は、我々は3つのプールを持って言うことができます、文字

によって標識様々な文書と各

プール1:A, B, C

プール2:D

プール3:E, F, G, H

私はAを検索し、AB、およびCを取得したいと考えています。 Cを検索すると、AB、およびCも取得したいと考えています。

Iという文書を追加し、プール1と2の基準を満たしている場合は、プール1と2をマージし、A, B, C, D, Iを検索するとすべてが返されます。

私はこれを非効率的に行う方法を知っています(各要素をキーとして新しい文書を作成し、各挿入時にすべての文書を更新します)が、より良い方法があるかどうか疑問に思っていましたか?私は、データ、特にデータベースの文書のように抽象的なもので、優れた可視化が問題を概念化に役立つと思い事前

+0

あなたは[indexing](https://docs.mongodb.com/manual/indexes/)を見ましたか? – displayName

+0

多分、単にキーを見るのではなく、ドキュメント内の要素を見るためにクエリを書き直すことを考えていたでしょうか? – displayName

+0

ドキュメント/コレクション*デザイン*を変更してクエリを簡単にすることができますか? – displayName

答えて

1

感謝。この問題は、深さが1以上のツリーを維持しようとする観点から見てください。具体的には、各ドキュメントはリーフであり、「プール」の一部であるものを決定する「ルール」はルートですルートはリーフとなるラベルのサブセットです)。

今、あなたがしたいことは、新しい葉を追加できることです。このリーフが複数のルートに接続できる場合は、それらのルートをマージする必要があります。これは、ルートが何であるかを更新し、影響を受けるツリーのすべてのリーフをこの新しいルートに向けることを意味します。

そうでなければ、新しい葉からそれがつながっている根まで、そして他のすべての葉に飛び回る必要があります。しかし、お互いの葉は潜在的に他の根につながる可能性があります。つまり、あなたはこのように何回も飛び回ることができます。これは非理想的な状況です。

このクエリが効率的になるためには、これらの「ルーツ」が何になるかを決定し、それに応じて更新する必要があります。たとえば、「プール」文書を保持し、必要に応じてこれらの「プール」を結合することができます。プールに含まれるラベルの配列であるlabelsフィールドを持つことによって、マージは、配列自体をマージするだけです。あるいは、共通のObjectId(特定のドキュメントに必ずしも付随するものではない)を使用して、この値をドキュメントを持つ代わりに一種の「擬似ルートノード」として使用することもできます。あなたが探索できる多くのオプションがあります。ただし、一般的には、個々のドキュメントのフィールド値の検査を単一の値チェックに減らすようにしてください(たとえば、各ドキュメントに他の関連するラベルの配列を置かないでください)。

これらのツリー構造を念頭に置いて、MongoDBクエリの観点からノードをトラバースすることを検討し、ノードをどのようにトラバースするかを決定し、1)ノード間で必要となるホップは一定時間の操作であり、2)データが失われることなく効率的かつ確実にそれらのルートをマージできることを保証します。

最後に、更新クエリが遅すぎると判断した場合は、インデックス作成の問題が発生している可能性があります。適切なインデックスを使用すると、数百万のドキュメントを含むコレクションの更新にはまったく時間がかかりません。さらに、multiアップデートを実行しておらず、代わりにドキュメントごとに個別のアップデートを実行している場合は、アップデート時間が長くなりネットワークオーバーヘッドが発生するため、アップデートがひどく書かれています。クロール。

関連する問題