簡體   English   中英

如何確保Neo4j節點在同一事務中添加到索引?

[英]How to ensure that Neo4j nodes are added to the index within same transaction?

我想將節點存儲到Neo4j中,在這里我不想多次存儲同一節點。 為此,我正在使用Neo4j索引API。

http://docs.neo4j.org/chunked/milestone/indexing-search.html

http://docs.neo4j.org/chunked/milestone/auto-indexing.html

但是,剛創建的節點未反映在索引中。

如何確保Neo4j節點在同一事務中添加到索引?

package graph

import org.neo4j.graphdb.Direction
import org.neo4j.graphdb.GraphDatabaseService
import org.neo4j.graphdb.Node
import org.neo4j.graphdb.Path
import org.neo4j.graphdb.Relationship
import org.neo4j.graphdb.RelationshipType
import org.neo4j.graphdb.Transaction
import org.neo4j.graphdb.factory.GraphDatabaseFactory
import org.neo4j.graphdb.traversal.Evaluators
import org.neo4j.graphdb.traversal.TraversalDescription
import org.neo4j.graphdb.traversal.Traverser
import org.neo4j.kernel.Traversal
import scala.sys.ShutdownHookThread
import collection.JavaConversions._
import java.io.File
import scala.collection.mutable
import org.neo4j.graphdb.factory.GraphDatabaseSettings

object indextest extends App {

  def deleteFileOrDirectory(file: File): Unit = {
    if (!file.exists()) return ;
    if (file.isDirectory()) for (child <- file.listFiles()) deleteFileOrDirectory(child)
    else file.delete()
  }

  val GRAPHLOCATION = "/tmp/testgraph"

  // setup Graph DB
  deleteFileOrDirectory(new File(GRAPHLOCATION))
  val graphDb = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(GRAPHLOCATION)
    .setConfig(GraphDatabaseSettings.node_keys_indexable, "name")
    .setConfig(GraphDatabaseSettings.node_auto_indexing, "true")
    .newGraphDatabase()

  // register shutdown hook thread
  ShutdownHookThread {
    graphDb.shutdown()
  }

  val tx = graphDb.beginTx
  val indexManager = graphDb.index()
  val nameIdsIndex = indexManager.forNodes("nameIds", Map("type" -> "exact"))

  val node1 = createOrFetchNode("A")
  val node2 = createOrFetchNode("A")

  tx.success()
  tx.finish()

  def createOrFetchNode(nodeName: String) = {
    val hits = nameIdsIndex.get("name", nodeName)
    val node = hits.getSingle()
    println(s"search for $nodeName -> list: ${hits.iterator.toList} node: $node")

    if (node == null) {
      val node2 = graphDb.createNode()
      node2.setProperty("name", nodeName)
      node2
    } else node
  }

}

當前輸出:

search for A -> list: List() node: null
search for A -> list: List() node: null

預期的輸出:

search for A -> list: List() node: null
search for A -> list: List(Node[1]) node: Node[1]

我究竟做錯了什么 ?

實際上,您有兩個索引:傳遞到配置時創建的auto_index (GraphDatabaseSettings.node_auto_indexing, "true")和第二個索引nameIdsIndex 第二個索引是手動索引,因此您必須顯式添加和刪除條目。 這就是為什么您在查詢中找不到任何內容的原因(不過您應該在auto_index中找到該節點)。

有特殊的機制可確保創建節點時的唯一性: http : //docs.neo4j.org/chunked/milestone/tutorials-java-embedded-unique-nodes.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM