web-dev-qa-db-ja.com

MongoDBにキーをまったく保存しない場合とnullを保存する

Mongoドキュメントを作成していて、フィールド{key, value}これには値がない場合があります。2つのオプションがあります。

  1. 書く {key, null}すなわち、フィールドにヌル値を書き込む
  2. そのドキュメントにキーを保存しないでください

両方のオプションは簡単にクエリ可能で、1つは{key : null}および{key : {$exists : false}}

アプリケーションシナリオに影響を与える2つのオプションの違いを考えることはできません(オプション2のストレージがわずかに少ないことを除きます)。

誰かが2つのアプローチのどちらかをもう一方よりも好む理由があるかどうか、そしてなぜですか?

[〜#〜] edit [〜#〜]

質問をした後、2つのケースでインデックスの動作が異なる可能性があることにも気付きました。つまり、オプション2に対してスパースインデックスを作成できます。

42
Zaid Masud

確かに3番目の可能性もあります:key: ""(空の値)

そして、あなたはヌル値についての特異性を忘れます。 key: nullに対するクエリは、キーがnullであるすべてのドキュメントを取得しますまたはキーが存在しない場合。

$exists:falseに対するクエリが、フィールドキーが存在しないドキュメントのみを取得する場合。

正確な質問に戻るには、クエリとデータが表すものに依存します。たとえば、ユーザーが値を設定してから設定を解除する必要がある場合は、フィールドをnullまたは空のままにしておく必要があります。必要ない場合は、このフィールドを削除できます。

35
AlphaB

MongoDBはフィールド名辞書の圧縮を使用しないため、field:nullはディスク領域とRAMを消費しますが、キーをまったく保存しないとリソースを消費しません。

16
Samuel García

本当に次のようになります。

  • あなたのシナリオ
  • クエリ方法
  • インデックスのニーズ
  • あなたの言語

私は個人的にヌルキーを保存することを選択しました。これにより、アプリへの統合がはるかに簡単になります。 Active RecordでPHPを使用し、null値を使用すると、アプリにフィールド依存のストレスをかける必要がないため、人生がずっと楽になります。また、複雑にする必要もありません。存在しない変数を設定するための魔法に対処するコード。

個人的には、""のような空の値を保存しません。注意しないと、null""の2つの空の値を使用でき、具体的にクエリするハザードハザードが発生するからです。そのため、空の値にはnullを個人的に好みます。

スペースとインデックスに関しては、この列を持たない行の数に依存しますが、null inを含むいくつかの余分なドキュメントのために、インデックスサイズの増加に本当に気付くとは思わないでしょう。ストレージの違いは特に対応する場合キー名も​​小さいです。大規模なセットアップでも同様です。

$existsnullの間のインデックスの使用方法ははっきりとわかりませんが、nullはMongoDBがスキーマレスであることを覚えているため、存在を照会するためのより標準化された方法です。ここでも、存在しない値とnullという2つの空の値が生成されます。どちらかを選択する方が良いでしょう。

nullを選択します。

7
Sammaye

考慮すべきもう1つのポイントは、Hibernate OGMなどのOGMツールを使用する場合です。

Javaを使用している場合、Hibernate OGMはJPA標準をサポートします。したがって、JPQLクエリを記述できる場合、OGMツールでサポートされている代替のNoSQLデータストアに切り替えると、理論的には簡単になります。

JPAは、Mongoの$ existsに相当するものを定義していません。そのため、コレクションにオプションの属性がある場合、同じ属性に対して適切なJPQLを作成できません。このような場合、属性の値がNULLとして格納されている場合、以下のような有効なJPQLクエリを記述することが可能です。

SELECT p FROM pppoe p where p.logout IS null;
2
Vinod