1

I am trying to write a cypher query which allows you to pass in a set of names as strings to find matching nodes and then return each node's id. I've been playing around with the language and came up with the following flawed query:

START person=node(*)
WHERE HAS (person.name)
WITH FILTER (name IN ['ryan','mike'] : person.name=name) AS matchedPersons
RETURN ID(matchedPersons)

Expected `matchedPersons` to be a node or relationship, but it was ``

If I return matchedPersons instead of ID(matchedPersons), I get this result:

+------------------------------------------+
| matchedPersons                           |
+------------------------------------------+
| ["ryan"] |
| ["mike"] |
| []                                       |
+------------------------------------------+
3 rows

In my database, I have three person nodes that have the names 'ryan', 'mike', and 'lucy'. I want to get the ID's of the people that match the names in the collection defined in the FILTER clause. How can I get the ID's of each person who has a name that matches at least one of the names in the collection?

Stephen D
  • 2,836
  • 4
  • 27
  • 40

1 Answers1

2

There's a much simpler way to write this query:

neo4j-sh (?)$  match (p:Person) where p.name in ['ryan', 'mike'] return id(p);
+-------+
| id(p) |
+-------+
| 14680 |
| 14681 |
+-------+
2 rows
96 ms

(Tested on some local data, so your IDs will be different).

OK, so that's how to do it. But here's the thing - you probably shouldn't look at, deal with, or care about the IDs of individual nodes. See this related question. Node IDs should be thought of as an implementation detail. All they'll ever do for you is provide a unique identifier, but you should make zero assumptions about what their value will be. Don't make assumptions like that they'll never change, or that they're always ordered in a certain way. If you need an identifier with actual meaning, use your own.

Community
  • 1
  • 1
FrobberOfBits
  • 17,634
  • 4
  • 52
  • 86
  • Interesting read, however I am getting the ID's to build a relationship using the Neo4JTemplate class. The create relationship method in that class calls for node id's. – Stephen D Oct 02 '14 at 13:38
  • 1
    Not familiar with that class or what you're trying to do there. All I can suggest is that if there's an alternate method that deals with a `Node` object instead of IDs, that would probably be preferable so that you can let someone else worry about the details of IDs. I try not to mess with them because 9 times out of 10 they're not what you want. You might have an exception though because of how you're using them, I'm not sure. – FrobberOfBits Oct 02 '14 at 13:49
  • 1
    these are the id's of the node, you can use the `template.query()` method with this query replacing the collection with a named parameter and returning p, then you have your nodes `template.query("match (p:Person) where p.name in {names} return p",map("names", asList("ryan","mike"))).to(Node.class);` – Michael Hunger Oct 02 '14 at 21:18
  • Hey @FrobberOfBits would you mind dropping me an email at michael@neo4j.org ? – Michael Hunger Oct 02 '14 at 21:19
  • @MichaelHunger I sent you an email. – FrobberOfBits Oct 03 '14 at 12:38