简体   繁体   中英

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

I want to store nodes into Neo4j, where I don't want to store same node more than once. For this I am using Neo4j indexing API.

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

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

But, the node just created is not reflected in the index.

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

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

EXPECTED OUTPUT:

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

What am I doing wrong ?

You actually have two indexes: the auto_index, that you create when you pass to the config (GraphDatabaseSettings.node_auto_indexing, "true") , and your second index nameIdsIndex . This second index is a manual one, therefore you have to explicitly add and remove entries from it. This is why you don't find anything with your query (you should find the node in the auto_index though).

There are special mechanisms for ensuring the uniqueness when creating nodes: http://docs.neo4j.org/chunked/milestone/tutorials-java-embedded-unique-nodes.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM