当前位置: 首页 > 知识库问答 >
问题:

在Cypher查询中处理空值

汪博艺
2023-03-14

我使用Neo4j java驱动程序从我的mysql数据库添加节点到Neo4j

我的问题是记录中的某些列值可能为null。我如何在cypher查询中处理它们,因为对于mysql表中的null值,它没有创建任何节点。

下面是我使用neo4j java驱动程序创建节点的代码

public void readObsTableAndCreateNode() throws Exception {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connect = DriverManager.getConnection("jdbc:mysql://localhost/openmrsnew?user=root&password=qwas");
            statement = connect.createStatement();
            resultSet = statement.executeQuery("select obs_id, person_id, concept_id, encounter_id, order_id, obs_datetime, value_text, date_created, creator, uuid, voided from obs where `obs`.`date_created` > '2018-09-20 00:00:00' and concept_id != 33334002 limit 2");

            List<HashMap<String, Object>> cypherQueriesList = new ArrayList<HashMap<String, Object>>();

            while (resultSet.next()) {

                HashMap<String, Object> cipherQueryParams = new HashMap<String, Object>();
                Integer obsId = Integer.parseInt(resultSet.getString("obs_id"));
                Integer personId = Integer.parseInt(resultSet.getString("person_id"));
                Integer conceptId = Integer.parseInt(resultSet.getString("concept_id"));
                Integer creator = Integer.parseInt(resultSet.getString("creator"));
                Integer voided = Integer.parseInt(resultSet.getString("voided"));
                Integer encounterId = encounterId = Integer.parseInt(resultSet.getString("encounter_id"));
                String date_created = resultSet.getString("date_created");
                String value_text= resultSet.getString("value_text");
                String uuid = resultSet.getString("uuid");           
                String obs_datetime= resultSet.getString("obs_datetime");

                ((HashMap<String, Object>) cipherQueryParams).put("creator", creator);
                ((HashMap<String, Object>) cipherQueryParams).put("valueText", value_text);
                ((HashMap<String, Object>) cipherQueryParams).put("uuid", uuid);
                ((HashMap<String, Object>) cipherQueryParams).put("dateCreated", date_created);
                ((HashMap<String, Object>) cipherQueryParams).put("obsDatetime", obs_datetime); 
                ((HashMap<String, Object>) cipherQueryParams).put("obsId", obsId);
                ((HashMap<String, Object>) cipherQueryParams).put("encounterId", encounterId);
                ((HashMap<String, Object>) cipherQueryParams).put("conceptId", conceptId);
                ((HashMap<String, Object>) cipherQueryParams).put("personId", personId);
                ((HashMap<String, Object>) cipherQueryParams).put("voided", voided);

                cypherQueriesList.add(cipherQueryParams);
            }

            HashMap<String, Object> cypherQuerybatch = new HashMap<String, Object>();
            cypherQuerybatch.put("batch", cypherQueriesList);

            // I am using merge because I dont want duplicated enteries

            String cypherQuery = "UNWIND {batch} as row MERGE (m:temp { obsId: row.obsId ,valueText: row.valueText, uuid: row.uuid, dateCreated: row.dateCreated , obsDatetime: row.obsDatetime })"
                    + " WITH m, row MATCH (c:Concept {conceptId: row.conceptId }) MERGE (m)-[:CONCEPT]->(c) "
                    + " WITH m, row MATCH (e:Encounter {encounterId: row.encounterId }) MERGE (m)-[:ENCOUNTER]->(e) "           
                    + " WITH m, row MATCH (u:Users {userId: row.creator }) MERGE (m)-[:USERS]->(u) "
                    + " WITH m, row MATCH (p:Person {personId: row.personId}) MERGE (m)-[:PERSON]->(p) "
                    + " RETURN m";

            runCypherWithParams(cypherQuery, cypherQuerybatch);

        } catch (Exception e) {
            throw e;
        } finally {
            close();
        }

    }



private void runCypherWithParams(String cypherQuery,  Map<String, Object> parameters) throws Exception{
        System.out.println("Posting Data to Neo4J browser...");
        try {
            connNeo4j = new ConNeo4j("bolt://localhost:7687", "neo4j", "qwas");
            connNeo4j.execQueryBySession(cypherQuery, parameters);                
        } catch (Exception e) {
            e.printStackTrace();
        }finally {

        }

    }



public void execQueryBySession(String query, Map<String, Object> parameters) {
        try {
            Session session = driver.session();
            StatementResult result = session.run(query, parameters);

            System.out.println("Success:- " + result);
        } catch (Exception e) {
            System.out.println("[WARNING] Null Row" + e.getMessage());
        }
    }

在neo4j浏览器控制台中,当我在cypher下面运行查询时,没有形成任何节点。

MERGE (m:Temp { obsId: 742241 ,valueText: NULL}) return m;

更新:我能够在Java处理空值。但是对于另一张桌子,我有一些奇怪的行为。

在Neo4j浏览器控制台中。我正在将参数设置为

:param batch: [{deathdateEstimated: 0, birthdateEstimated: 1, creator: 6, birthdate: "2018-01-01", dateCreated: "2018-09-20 04:08:0", gender: "M", personId: 1, voided: 0, uuid: "d7132677-6f7b-aeb8-af5f-850d621b6bbb"}, {deathdateEstimated: 0, birthdateEstimated: 1, creator: 1, birthdate: "2018-01-01", dateCreated: "2018-09-20", gender: "M", personId: 2, voided: 0}]

当我运行下面的密码查询时,只创建一个节点,而不是两个。

UNWIND {batch} as row MERGE (m:tempPerson) ON CREATE SET m+=row WITH m,row MATCH (u:Users {userId: row.creator }) MERGE (m)-[:USERS]->(u) return m;

共有2个答案

卓学智
2023-03-14

如何解决您的问题在Java方面,只需检查每个输入值为"not null",并将其添加到您的cypherQueryParameter HashMap只有在这种情况下?

丁淇
2023-03-14

从Neo4j文档:

虽然可以在匹配中的节点变量为null的情况下执行匹配(例如来自失败的可选匹配),但不能创建或合并具有null节点变量的模式。

您可以使用的另一个选项是“合并”中提供的“创建”和“匹配”选项。但是,此查询取决于您的节点可以使用“obsId”字段进行唯一标识这一事实。

MERGE (m:Temp { obsId: 742241}) 
ON CREATE SET m.valueText = NULL
ON MATCH SET m.valueText = NULL
return m;
 类似资料:
  • 我是Neo4J的新手,我正在尝试为基于时空的高可用性查询建立一个概念证明。 我有一个设置,有2个独立的Neo4J企业服务器和一个运行嵌入式HA Neo4J服务器的Java应用程序。 一切都很容易设置,基本查询也很容易设置和高效。另外,按照预期执行从Neo4J SpatialRepository派生的查询。 我正在努力理解的是如何使用SDN与任何其他where子句组合进行空间查询。作为一个微不足道的

  • 问题内容: 我正在使用JPA,hibernate3。 当没有空值或空值时,此查询就像一个超级按钮。但是 traceEntityVO.getLotNumber(),traceEntityVO.getMfrLocId(),traceEntityVO.getExpDate()的 值可能为null或为空 。 在这种情况下,将针对变量而不是 null 条件来检查值’null’或’‘ 。当我不确定参数值是否为

  • 我是JPA新手,这里是我的一个查询,我有几个参数作为查询的一部分,任何参数都可以是空值

  • 我正在使用REST与neo4j DB交互。

  • Cypher对我来说似乎比Gremlin要清楚得多,总的来说,Neo4j的家伙似乎都在和Cypher一起。但是--如果Cypher与Gremlin相比是有限的--我真的想提前知道这一点。