关于java:如何保证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节点被添加到同一个事务内的索引中?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
  }

}

电流输出:

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

预期输出:

1
2
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