neo4j - how to run queries with 1000 objects via rest api

拜拜、爱过 提交于 2019-12-20 03:14:42

问题


I'm need run queries with 1000 objects. Using /batch endpoint I can get this to work but is too slow (30 seconds with 300 items).

So I'm trying the same approach as said in this docs page: http://docs.neo4j.org/chunked/2.0.1/rest-api-cypher.html#rest-api-create-mutiple-nodes-with-properties

POST this JSON to http://localhost:7474/db/data/cypher

{
    "params": {
        "props": [
            {
                "_user_id": "177032492760",
                "_user_name": "John"
            },
            {
                "_user_id": "177032492760",
                "_user_name": "Mike"
            },
            {
                "_user_id": "100007496328",
                "_user_name": "Wilber"
            }
        ]
    },
    "query": "MERGE (user:People {id:{_user_id}}) SET user.id = {_user_id}, user.name = {_user_name} "
}

The problem is I'm getting this error:

{ message: 'Expected a parameter named _user_id',
  exception: 'ParameterNotFoundException',
  fullname: 'org.neo4j.cypher.ParameterNotFoundException',
  stacktrace:
  ...

Maybe this works only with CREATE queries, as showing in the docs page?


回答1:


Use FOREACH and MERGE with ON CREATE SET:

 FOREACH (p in {props} | 
    MERGE (user:People {id:{p._user_id}}) 
      ON CREATE  user.name = {p._user_name})

POST this JSON to http://localhost:7474/db/data/cypher

{
    "params": {
        "props": [
            {
                "_user_id": "177032492760",
                "_user_name": "John"
            },
            {
                "_user_id": "177032492760",
                "_user_name": "Mike"
            },
            {
                "_user_id": "100007496328",
                "_user_name": "Wilber"
            }
        ]
    },
    "query": "FOREACH (p in {props} | MERGE (user:People {id:{p._user_id}}) ON CREATE  user.name = {p._user_name}) "
}



回答2:


Actually, the equivalent to the example in the doc would be:

{
    "params": {
        "props": [
            {
                "id": "177032492760",
                "name": "John"
            },
            {
                "id": "177032492760",
                "name": "Mike"
            },
            {
                "id": "100007496328",
                "name": "Wilber"
            }
        ]
    },
    "query": "CREATE (user:People {props})"
}

It might be legal to replace CREATE to MERGE, but the query may not do what you expect.

For example, if a node with the id "177032492760" already exists, but it does not have the name "John", then the MERGE will create a new node; and you'd end up with 2 nodes with the same id (but different names).




回答3:


Yes, a CREATE statement can take an array of maps and implicitly convert it to several statements with one map each, but you can't use arrays of maps that way outside of simple create statements. In fact you can't use literal maps the same way either when you use MERGE and MATCH. You can CREATE ({map}) but you have to MATCH/MERGE ({prop:{map}.val} i.e.

// {props:{name:Fred, age:2}}
MERGE (a {name:{props}.name}) 
    ON CREATE SET a = {props}

For your purposes either send individual parameter maps with a query like above or for an array of maps iterate through it with FOREACH

FOREACH (p IN props |
    MERGE (user:People {id:p._user_id}) 
        ON CREATE SET user = p)


来源:https://stackoverflow.com/questions/22799123/neo4j-how-to-run-queries-with-1000-objects-via-rest-api

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!