3

これはベストプラクティスの質問です。私は高度に構造化されたデータの検索バックエンドを実装しています。これは本質的に、オントロジー、用語、およびそれらの間の複雑なマッピング セットで構成されています。Neo4j は自然にフィットするように思われ、いくつかのプロトタイピングの後、neo4j と通信する方法として py2neo を使用することにしました。これは主に、バッチ操作のサポートが優れているためです。これは何よりもベスト プラクティスの質問です。

私が不満を感じているのは、コードに入れたい高レベルの抽象化のタイプを導入するのに問題があるということです - オブジェクトをミニオームとして直接使用することに固執していますが、私はアトミックな残りの呼び出しを何度も行っているため、パフォーマンスが低下します (かなり大きなデータ セットがあります)。

私が行ってきたことは、クエリ結果を取得し、それらに対して get_properties を使用してオブジェクトをバッチ水和することです。これは優れたプリフォームであり、最初にこのルートをたどった理由ですが、これにより (ノード、プロパティ) を私のコードの周りに配置すると、仕事は完了しますが、きれいではありません。まったく。

だから私が求めているのは、py2neo でかなり豊富なオブジェクト グラフを操作し、パフォーマンスを維持しながら ORM のような機能を後で取得するためのベスト プラクティスがどこかにあるかどうかということです (私の場合、可能な限り多くのことを行うことを意味します)。バッチ クエリ)

4

2 に答える 2

4

あなたが何を望んでいるのか理解できているかどうかはわかりませんが、同様の問題がありました。多くの呼び出しを行い、多くのノード、インデックス、および関係を作成したかった.. (約 120 万) . py2neo を使用してノード、リレーションシップ、インデックス、およびラベルをバッチで追加する例を次に示します。

from py2neo import neo4j, node, rel
gdb = neo4j.GraphDatabaseService("<url_of_db>")
batch = neo4j.WriteBatch(gdb)

a = batch.create(node(name='Alice'))
b = batch.create(node(name='Bob'))

batch.set_labels(a,"Female")
batch.set_labels(b,"Male")

batch.add_indexed_node("Name","first_name","alice",a) #this will create an index 'Name' if it does not exist
batch.add_indexed_node("Name","first_name","bob",b) 

batch.create(rel(a,"KNOWS",b)) #adding a relationship in batch

batch.submit() #this will now listen to the db and submit the batch records. Ideally around 2k-5k records should be sent 
于 2013-11-08T17:02:40.373 に答える
2

ベストプラクティスを求めて以来、私が遭遇した問題は次のとおりです。

バッチで py2neo を使用して多数のノード (~1M) を追加すると、neo4j サーバーがメモリ不足になると、プログラムが遅くなったりクラッシュしたりすることがよくあります。回避策として、送信を複数のバッチに分割しました。

from py2neo import neo4j

def chunker(seq, size):
    """
    Chunker gets a list and returns slices 
    of the input list with the given size.
    """
    for pos in xrange(0, len(seq), size):
        yield seq[pos:pos + size]


def submit(graph_db, list_of_elements, size):
    """
    Batch submit lots of nodes.
    """

    # chunk data
    for chunk in chunker(list_of_elements, size):

        batch = neo4j.WriteBatch(graph_db)

        for element in chunk:
            n = batch.create(element)
            batch.add_labels(n, 'Label')

        # submit batch for chunk
        batch.submit()
        batch.clear()

これをさまざまなチャンクサイズで試しました。私にとっては、バッチあたり最大 1000 ノードで最速です。しかし、これはneo4jサーバーのRAM/CPUに依存すると思います.

于 2013-11-12T09:46:25.143 に答える