【问题标题】:How to add unique data to a neo4j graph database如何将唯一数据添加到 neo4j 图数据库
【发布时间】:2017-03-13 10:48:53
【问题描述】:

我将迭代数据添加到我的 neo4j 数据库中,但我不知道如何覆盖或更新现有数据以及检查数据是否已存在其中。

基本上我有一组带有相应 id 的电影,例如:

[
  {id: 'gameofthrones', genre: 'fantasy', release: '2017'},
  {id: 'inception', genre: 'scifi', release: '2010'},
  ...
]

我可以按如下方式添加电影:

CREATE 
(m1:Movie {id: 'gameofthrones', genre: 'fantasy', release: '2017'}), 
(m2:Movie {id: 'inception', genre: 'scifi', release: '2010'}) 

但是,当我运行脚本两次时,它会创建 4 个节点,而不是保留在两个节点上。

所以我的问题是,如何确保它检查节点 id 是否已经存在,如果存在则覆盖它而不是创建新节点?

我试过了(但只添加了属性)

// data
attributes['id']         = 'gameofthrones';
attributes['genre']     = 'fantasy';
...

// query
MERGE ( s:Movie {attributes}.id)
ON CREATE SET ( s:Movie {attributes} )

我在NodeJS 中调用如下:

executeQuery(queryStr, {"attributes": attributes})

// cypher (nodejs)
function executeQuery(queryStr, params) {
    var qq = Q.defer();
    db.cypher({
        query: queryStr,
        params: params,
    }, function (error, results) {
        if (error) {
            qq.reject(error);
        } else {
            if (results.length != 0) {
                qq.resolve(true);
            } else {
                qq.resolve(false);
            }
        };
    });
    return qq.promise;
};

【问题讨论】:

  • 如何加载数据? apoc.load.json ? -- 使用 apoc.load.json 更新示例
  • 嗯,不,我只是将数据作为对象。

标签: neo4j graph-databases graphenedb


【解决方案1】:

您必须将查询更改为此

MERGE ( s:Movie {attributes}.id)
ON CREATE SET s += {attributes}
ON MATCH SET s += {attributes} // optional

这应该可以,但您应该使用 apoc.map.clean(),这样您就不会设置 id 两次,这可能会导致一些问题。

MERGE ( s:Movie {attributes}.id)
ON CREATE SET s += apoc.map.clean({attributes},['id'],[])

【讨论】:

  • 工作。谢谢!
  • 最好把属性和id分开。这样它就不会被覆盖,这(可能)会触发另一个索引更新
【解决方案2】:

您可以使用MERGE 子句实现此目的,如下所示

MERGE (m1:Movie {id: 'gameofthrones'})
ON CREATE SET m1.genre = 'fantasy', m1.release = '2017'

MERGE (m2:Movie {id: 'inception'})
ON CREATE SET m2.genre: 'scifi', m2.release = '2010' 

理想情况下,您希望使用参数而不是文字字符串来创建查询。如果您使用 apoc.load.json,您可以实现此目的

with "file:///home/sample.json" as url // can be also http://url/sample.json
CALL apoc.load.json(url) yield value
UNWIND value as item
MERGE (m1:Movie {id: item.id})
ON CREATE SET m1.genre = item.genre, m1.release = item.release

具有 apoc 函数的动态属性示例:

with "file:///home/sample.json" as url // can be also http://url/sample.json
CALL apoc.load.json(url) yield value
UNWIND value as item
MERGE (m1:Movie {id: item.id})
ON CREATE SET m1 += apoc.map.clean(item,['id'],[])

或者如果您没有 apoc 插件:

with "file:///home/sample.json" as url // can be also http://url/sample.json
CALL apoc.load.json(url) yield value
UNWIND value as item
MERGE (m1:Movie {id: item.id})
ON CREATE SET m1 += item

请注意,id 将首先合并,然后使用ON CREATE SET 更新,并且您希望避免两次写入单个属性,使用 apoc 及以上查询我们可以实现这一点

【讨论】:

  • 谢谢。所以我用参数尝试过,但我没有让它工作。更新了我的问题。
  • 问题是,属性的​​数量是动态变化的。我不想每次都在字符串中设置属性。
  • 添加了一个动态属性的例子
  • 我没有像您那样获取检索数据的目的。我已经拥有对象形式的数据(预加载)。为什么我需要以 JSON 格式再次获取它?
  • 不需要只是一个例子......如果你已经有一个对象,你可以跳过 apoc.load.json 并这样做with my_object as value UNWIND value as item MERGE (m1:Movie {id: item.id}) ON CREATE SET m1 += item
猜你喜欢
  • 2014-04-28
  • 2016-10-21
  • 2017-06-10
  • 2013-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-20
相关资源
最近更新 更多