如何确保在同一事务中将Neo4j节点添加到索引中?

时间:2013-12-16 14:55:16

标签: java scala neo4j

我想将节点存储到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
  }

}

CURRENT OUTPUT:

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]

我做错了什么?

1 个答案:

答案 0 :(得分:2)

您实际上有两个索引:auto_index,您在传递给配置(GraphDatabaseSettings.node_auto_indexing, "true")时创建的,以及您的第二个索引nameIdsIndex。第二个索引是手动索引,因此您必须显式添加和删除条目。这就是为什么你没有找到任何查询的原因(你应该在auto_index中找到节点)。

在创建节点时,有一些特殊的机制可以确保唯一性:http://docs.neo4j.org/chunked/milestone/tutorials-java-embedded-unique-nodes.html