【问题标题】:No result with Cypher after batchinserting with indexing使用索引批量插入后,Cypher 没有结果
【发布时间】:2013-06-10 19:22:41
【问题描述】:

我对 neo4j 很陌生。我读过这个问题 (Cypher Query not finding Node) 但它不起作用。我收到错误消息,找不到 auto_node_index。也许是因为我使用的是 BatchInserter?

对于我的实验,我使用的是 neo4j 1.8.2 和带有嵌入式数据库的编程语言 Java。

我想使用 BatchInserter 和 BatchInserterIndex 将一些数据放入数据库,如 http://docs.neo4j.org/chunked/milestone/batchinsert.html 中所述。

    BatchInserter myInserter = BatchInserters.inserter(DB_PATH);
    BatchInserterIndexProvider indexProvider =
            new LuceneBatchInserterIndexProvider( myInserter );
    BatchInserterIndex persons =
            indexProvider.nodeIndex( "persons", MapUtil.stringMap( "type", "exact" ) );
    persons.setCacheCapacity( "name", 10000 );

首先,我从 TGF 文件中读取数据,创建节点并将其放入插入器,如下所示:

    properties = MapUtil.map("name", actualNodeName, "birthday", birthdayValue);
    long node = myInserter.createNode(properties);
nodes.add(node);
persons.flush();

插入工作正常,但是当我想用 Cypher 搜索节点时,结果为空

    ExecutionEngine engine = new ExecutionEngine( db );
    String query =
        "start n=node:persons(name='nameToSearch')  "
        + " match n-[:KNOWS]->m " 
        + " return n.id, m ";
    ExecutionResult result = engine.execute( query );
    System.out.println(result);

另一方面,当我使用 Traverser 类并在根节点上开始搜索时,我收到了由名为“nameToSearch”的节点连接的节点。

谁能解释一下,为什么我无法使用 Cypher 获取节点!

这里是批量插入的完整方法:

 public long batchImport() throws IOException{

    String actualLine;
    ArrayList<Long> nodes = new ArrayList<Long>();
    Map<String,Object> properties = new HashMap<String,Object>();

    //delete all nodes and edges in the database
    FileUtils.deleteRecursively(new File(DB_PATH ));

    BatchInserter myInserter = BatchInserters.inserter(DB_PATH);
    BatchInserterIndexProvider indexProvider =
            new LuceneBatchInserterIndexProvider( myInserter );
    BatchInserterIndex persons =
            indexProvider.nodeIndex( "persons", MapUtil.stringMap( "type", "exact" ) );
    persons.setCacheCapacity( "name", 10000 );

    long execTime = 0;
    try{
        //Get the file which contains the graph informations
        FileReader inputFile = new FileReader(UtilFunctions.searchFile(new File(PATH_OUTPUT_MERGED_FILES), "nodesAndEdges").get(0));
        LineNumberReader inputLine = new LineNumberReader(inputFile);

        // Read nodes up to symbol #
        execTime = System.nanoTime();
        while ((actualLine=inputLine.readLine()).charAt(0) != '#'){

        StringTokenizer myTokenizer = new StringTokenizer(actualLine);
        // Read node number 
        String actualNodeNumber = myTokenizer.nextToken();
        // Read node name
        String actualNodeName = myTokenizer.nextToken() + " " + myTokenizer.nextToken();
        //Read property             
        myTokenizer.nextToken();
        String actualNodePropertyKey = BIRTHDAY_KEY;
        String actualNodePropertyValue = myTokenizer.nextToken();
        actualNodePropertyValue = actualNodePropertyValue.substring(1, actualNodePropertyValue.length()-1);

      // Insert node information                        
        properties = MapUtil.map("name", actualNodeName, "birthday", actualNodePropertyValue, "id", actualNodeNumber);
        long node = myInserter.createNode(properties);
        nodes.add(node);
        persons.flush();
    }

    // Read edges up to end of file
    int countEdges = 0;
    while ((actualLine=inputLine.readLine()) != null){
        StringTokenizer myTokenizer = new StringTokenizer(actualLine);
        // Read start node number 
        String actualStartNodeNumber = myTokenizer.nextToken();
        // Read destination node number 
        String actualDestinationNodeNumber = myTokenizer.nextToken();
        // Read relationship type
        String actualRelType = myTokenizer.nextToken();

        // Insert node information into ArrayList
        int positionStartNode = Integer.parseInt(actualStartNodeNumber);
        int positionDestinationNode = Integer.parseInt(actualDestinationNodeNumber);

        properties.clear();

        if (countEdges == 0) {
            myInserter.createRelationship(0, nodes.get(positionStartNode-1), RelType.ROOT, properties);
            myInserter.createRelationship(nodes.get(positionStartNode-1), nodes.get(positionDestinationNode-1), RelType.KNOWS, properties);
        }
        else
        {
            myInserter.(nodes.get(positionStartNode-1), nodes.get(positionDestinationNode-1), RelType.KNOWS, properties);
        }
        countEdges++;
    }                 
    indexProvider.shutdown();
    myInserter.shutdown();
    execTime = System.nanoTime() - execTime;
    // Close input file
    inputLine.close();
    inputFile.close();

    }
    catch (Throwable e){
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
    return execTime; 
 }      

【问题讨论】:

  • 在您的第二个代码示例中,您有nodes.add(node)nodes 定义在哪里?
  • 抱歉,这不是完整的代码 sn-p。 nodesmyInserter 之前定义一行:ArrayList&lt;Long&gt; nodes = new ArrayList&lt;Long&gt;();
  • 你应该先从 "start n=node(*) return n" 开始,看看数据库上是否有任何东西!这样您就可以知道是导入问题还是查询问题...
  • 查询start n=node(*) return n 有效。使用 Traverser 类也可以正常工作。只有索引不起作用。 :(

标签: neo4j cypher


【解决方案1】:

您缺少对profiles.add(node, &lt;indexProperties&gt;) 的呼叫。因此,您永远不会向索引添加任何内容。

【讨论】:

  • 谢谢!我像蝙蝠一样瞎了眼,没看见! :( 我忘了声明persons.add(node, properties)
【解决方案2】:

使用 Batchinserter API 的代码在 BatchInserterIndexProviderBatchInserter 上调用 shutdown() 至关重要。也许您在代码中错过了这一点。

如果这不能解决问题,请发布您的代码。

【讨论】:

  • 不幸的是,这不是我的错。我已经更改了我的帖子并将完整的方法放在帖子的末尾。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 2016-07-30
  • 1970-01-01
相关资源
最近更新 更多