2012-03-26 8 views
5

これはもっと実際にはLuceneに関する質問ですが、これはneo4jデータベースのコンテキストにあります。Neo4jの索引付け(Luceneを使用) - ノードのタイプを整理するのに適していますか?

私は、50種類ほどのノードタイプに分かれているデータベースを持っています(他のタイプのdbsでは "コレクション"または "テーブル"なので)。それぞれにはインデックスを作成する必要のあるプロパティのサブセットがあり、一部は同じ名前を共有しているものもあれば、そうでないものもあります。

検索するとき、私はいつも特定のタイプのノードを見つけたいと思います。私はこれを組織する3つの方法を参照することができます

:インデックス「foo」で、'id'='1234'

  • タイプごとに1つのインデックスを、プロパティは、インデックスフィールドに自然にマッピングされます。

  • 各フィールドはプロパティ名にマップされ、値の一部として型を含めるか('id'='foo:1234')、ノードが返されるとノードをチェックします(重複は非常に稀です)。

  • 単一のインデックスのtypeは、フィールド名の一部です('foo.id'='1234')。

作成すると、データベースは読み取り専用です。

利便性、サイズ/キャッシュ効率、またはパフォーマンスの面で利点がありますか?

私が理解しているように、最初のオプションでは、neo4jは各タイプに対して別々の物理インデックスを作成しますが、これは最適ではないようです。 3番目には、ほとんどのluceneドキュメントでフィールドの小さなサブセットしか持たず、何かに影響があるかどうかはわかりません。

+0

インデックスの全体的なサイズが小さくなるため、それぞれのタイプごとに個別のインデックスを持つ方が便利ですばやく表示されます。しかし、私は何かが欠けているかもしれません。 – biziclop

+0

@biziclop:個々の指標の開閉を管理しなければならないので、実際には私にとっては最も不便なようでした。私の理解では、全体のサイズも大きくなります(jpountzの答えを参照)。 – Dmitri

+0

@Dimitri明らかに、全体的なサイズは大きくなりますが、問題は次のとおりです。あるいは、他のタイプより頻繁に検索されるタイプもありますか?いずれにしても、私がやることは、最も便利なソリューションを実装し、それがうまくいくかどうかを確認することです。そうであれば、勝者がいます。 – biziclop

答えて

1

用語辞書などの一部のデータが共有されるため、1つのインデックスはいくつかの小さなインデックスよりも小さくなります。しかし、用語辞書検索はO(lg(n))演算であるため、より大きな用語辞書の検索は少し遅くなる可能性があります。 (インデックスが50個の場合は、6(2^6> = 50)個の比較が必要になります)、

小さいインデックスのもう1つの利点は、OSキャッシュクエリをより速く実行させる可能性があります。

代わりにあなたのオプション2と3の、私はインデックス2つの異なるフィールドidtypeだろうとの検索(id:IDとtype:TYPE)が、それはのNeo4jで可能である場合、私は知りません。

+0

複数のフィールドを使用することは可能ですが、少し自然ではありません(これが理由です)。実装固有のクエリ文字列を直接インデックスエンジンに渡します。もっと一般的な 'index.get(field、value)' APIを使う方が好きです。 – Dmitri

+0

次に、最も自然な2番目のオプションを選択します(ID:TYPE + ID) – jpountz

1

spring-data-neo4jは、最初のアプローチを使用しています。これは、各タイプごとに異なるインデックスを作成します。だから私はそれが一般的なシナリオのための良い選択だと思います。しかし、あなたの特別なケースでは、あなたが言うように、それは最適ではないかもしれません。私はパフォーマンスを測定するためにいくつかのベンチマークを実行します。

他の2つは、ちょっと人工的なようです。あなたは、おそらく正しいとは言えない同じインデックス内の完全に無関係な情報に索引付けしています。

+0

関連のないデータを一緒に索引付けする際に問題が発生するかどうかわかりません。たとえば、これらのプロパティのほとんどは索引付けされます単一の「属性値」テーブルに格納されます。 – Dmitri

+0

ええ、あなたは正しいかもしれません。フルテキストインデックス作成では、それは奇妙ですが、neo4jストアをサポートするインデックスとして使用しているので、それほど悪くはありません。 – Bozho

2

Railsプロジェクトで使用するために、Neo4j over REST用の接続アダプターActiveRecordをビルドしたときに、この問題が最近発生しました。 ActiveRecordActiveRelationは両方ともSQL構文との緊密な結合を持っているため、すべてをNoSQLに収めるのが難しくなりました。最善の解決策になるが、ここで私はそれを解決する方法だしない場合があります。

  1. 2つのキーの下のノードをインデックス化model_indexという名前のインデックスを作成し、typeキーでtypemodel
  2. インデックス検索は現在ただ一つの値で発生model 。これは主に、グラフに表示されているすべてのモデルの一覧を取得できるSQL機能を実現するために導入されたものです。
  3. modelを使用したインデックス検索は、システムの異なるモデル名に対応する値で行われます。これは、主にDESC <TABLENAME>の機能を実現するためのものです。
  4. CREATE TABLEのように各テーブルを作成すると、ノードプロパティにテーブル定義属性が格納されたノードが作成されます。
  5. 作成されたノードのインデックスはmodel_indexで、type:modelmodel:<model-name>です。これにより、新しく作成されたモデルが 'テーブル'のリストに表示され、modelキーでインデックスルックアップによってモデルノードに直接アクセスすることもできます。
  6. model(ケースのタイプ)ごとに作成されたレコードごとに、instancesとラベル付けされた発信エッジがモデルノードからこの新しいレコードに向けて作成されます。 v[123] :=> [instances] :=> v[245]ここで、v [123]はモデルノードを表し、v [245]はv [123]のタイプのレコードを表します。
  7. 指定されたタイプのインスタンスをすべて取得する場合は、model:<model-name>model_indexを検索してモデルノードに到達し、instancesとラベル付けされた送信エッジ上のすべての隣接ノードをフェッチできます。フィルタリングされたルックアップは、フィルタおよび他の複雑なトラバーサルを適用することによってさらに達成することができる。

が2Xを含み、1つのインデックスのルックアップ及びシングルレベルトラバーサルを介して有効なレコードの検索を実現するため、上記溶液が目詰まりmodel_indexを防止します。

あなたの場合、異なるタイプのノードは互いに隣接していませんが、そうしたい場合でも、任意のノードのタイプは、入力ノードがinstancesの隣接ノードを検索するだけで判断できます。さらに、私はSpringDataGraphのこのインスタンスを隣接ノードの参照を避けるために__type__プロパティを格納するパターンを組み込むことを検討しています。

私は現在、ほとんどすべての目的で、ARELをGremlinスクリプトに翻訳しています。私のARアダプタのソースコードは、https://github.com/yournextleap/activerecord-neo4j-adapter

で見つけることができます。 :)

+0

これは私のオプション "2b"のように聞こえます:すべてをまとめて索引付けし、グラフを使用してタイプをフィルタリングします(エッジチェックを使用するか、またはタイプ・プロパティを指定します)。私は、オプション3に傾いていると思うので、フィルタリングされた検索はインデックス内で完全に行える。 – Dmitri

+0

インデックスにあまりにも頼ることの1つの欠点は、グラフをGraphMLまたはGraphSONにエクスポートする必要があるときに、インデックスを保持しない場合、グラフを他の場所にインポートするときにインデックスを再生成する必要があるということです。グラフ上のすべてを索引付けすることは、輸出 - >輸入のために高いターンアラウンド時間を意味する可能性があります。また、ルートノードから切断されたサブグラフがある場合、そのような場合にインデックスを失うと、データが失われ、サブグラフに到達するための絶対的なオプションがなくなる可能性があります。 – rhetonik

+0

以前にエクスポートされたGraphML/SONからグラフをインポートする場合に備えて、ルートノードからすべてのノードをトラバースできるようにすることをお勧めします。 – rhetonik

関連する問題