Cardinality issues are the most frequent culprit in slow or incorrect Cypher queries. Because of this, understanding cardinality, and using this understanding to manage cardinality issues, is a critical component in Cypher query tuning, and query correctness in general. A note about the following. If two different result sets are needed, two separate queries are built, each with its own source-to-target flow of data. However, I’ve seen more than a few queries (typically in the form of vendor stored procedures, which, of course, cannot be edited) which return more than one set of results in a single execution.
Track tasks and feature requests
Join 36 million developers who use GitHub issues to help identify, assign, and keep track of the features and bug fixes your projects need.
Sign up for free See pricing for teams and enterprises Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
commented Apr 10, 2014
In Neo4j 1.9, I could perform an operation on multiple nodes with one query, by passing in multiple IDs for a START point. E.g.:In Neo4j 2.0, I have to construct a WHERE clause that manually checks each value. E.g.:Would you guys be open to expanding the MATCH (user:User {prop: {val}}) syntax to make multiple allowed values easier to specify?-- Strawman proposal: MATCH (user:User {id: [{ids}]}) . That'd be equivalent to the above query, and the ids param would be required to be an array just like it is above as well.(You could still do MATCH (user:User {id: {ids}}) to specify a single array value.)-- I asked in #2228 (comment) whether MATCH (user:User {id}) could be supported as a DRYer shorthand for today's MATCH (user:User {id: {id}}) .If that's something you guys would be open to, then the equivalent strawman for this shorthand would be MATCH (user:User [{id}]) to specify multiple values. |
commented Apr 10, 2014
I'm not sure I understand why the use of WHERE with IN is problematic, given it seems much clearer and it's unambiguous.@aseemk Can you do some examples without the param? Params are simply literal substitutes, so the examples need to be unambiguous when there is a literal placed there as an alternative. |
commented Apr 10, 2014
Ah, good to know that params are simply literal substitutes. My strawman probably still works though? MATCH (user:User [{id: [1, 2, 3]}]) . That obv looks awful, but given that you would/should always use params, MATCH (user:User [{id}]) doesn't look so bad.It's not that WHERE ... IN is problematic, it's that it's a bit cumbersome and indirect. I wouldn't say it's much clearer. Single node MATCH (user:User {id: {id}}) (or my requested MATCH (user:User {id}) ) is what's clear — that's presumably the reason you guys added that ability to specify a key property in the MATCH directly. You lose that ability with multiple node lookups.This is subjective, and I fully admit that. Hence my calling this request 'sugar'. =D |
commented Apr 10, 2014
@aseemk How does MATCH (u:User [{id: [1,2,3]}]) work if I also want a constraint on a second property? eg. active: true |
commented Apr 10, 2014
BTW - we only recently added the ability to put predicates inside MATCH . Before it was always necessary to use WHERE ! Personally I find that using WHERE makes it much more obvious that it is a selection constraint. Having predicates inside the match is not as clear to me, but is ok for exact constraints. Of course, that's subjective :) |
commented Apr 11, 2014
@cleishm: good q re: another constraint. I'd say one reasonable answer to me is to require that second constraint to be declared via WHERE . 'Make common things easy, and uncommon things possible' isn't quite the quote, but something like it. ;) |
commented Apr 11, 2014
Given we already support multiple, like MATCH (:User {name: 'aseem', active: true}) - how would this proposed restriction affect that? Having multiple different rules and constraints seems overly complex for something that's no super common and is already possible using IN ;) |
commented Apr 12, 2014
I'm not proposing changing any current syntax. No valid Cypher today would break! I'm proposing adding MATCH (:User [{name}]) as shorthand for MATCH (user:user) WHERE user.name IN {name} . And I'd be okay with this shorthand not supporting multiple properties (just because I can't think of a simple, nice syntax for that so far).If implementing something like this is too difficult or impractical, totally understandable. Just wanted to raise this as a feature request, because we definitely have several queries that take advantage of 1.9 START n=node({ids}) , and it'd (subjectively, to me) be nice to maintain some shorthand like that. =) |
commented Apr 13, 2014
I'm still not sure what that would look like if you did replaced the param with a literal - MATCH (:User [[1, 2, 3]]) doesn't make any sense. |
commented Apr 13, 2014
Not sure if you missed my related request that a parametrized MATCH (:User {name}) be shorthand for MATCH (:User {name: {name}}) . Does that answer your q?(So MATCH (:User [{name}]) would expand to MATCH (:User [{name: ['A', 'B', 'C']}]) , which would mean MATCH (user:User) WHERE user.name IN ['A', 'B', 'C'] .) |
commented Apr 13, 2014
The param syntax, e.g. {param} , indicates a literal replacement for whatever is supplied in the parameter. So we can't use the name of the parameter to also assume the property name - they need to be specified separately. |
commented Apr 13, 2014
Okay, what about {{param}} ?I'm open to different solutions; I'm just making requests to reduce the slight verbosity and repetitiveness of these kinds of Cypher cases. Consider this an open-ended feature request. |
commented Apr 13, 2014
I'm happy to continue exploring ideas. The only concern I have is that adding more symbolic sugar (like {{..}} ) begins to obscure the readability and ease of understanding of the query itself - one has to know what this special syntax means in order to understand the query behavior. (Variable/Parameter substitution is a common idiom in most query languages, but this proposal is something different as it combines substitution with logical predicate specification.)Cypher values readability and ease of understanding over brevity. So if we can find a way to achieve the brevity you're looking for without sacrificing the former, that would be cool. |
closed this May 22, 2014
reopened this May 22, 2014
commented May 22, 2014
Sorry @aseemk - closed a stack of issues accidentally. Although we haven't continued this discussion for a little while, so maybe we should - whilst we go and think about some good alternatives? |
commented Jul 22, 2014
Sorry for the delay @cleishm!
Those are great points.
How about this? To be equivalent to: This is low-priority, so if you guys feel a shorthand syntax here realistically just won't happen, I understand. Feel free to close this issue in that case. |
commented Jul 23, 2014
I don't think that this kind of syntactic sugar is worth changes in Cypher syntax. There is some diversity in style of queries already (I mean, compare constraints and indices creation!), so keeping in mind one more subtlety won't make a developer feel good about the language he's writing in. |
commented Jul 23, 2014
I understand. In general, I feel like there's a lot of room for reducing the verbosity and boilerplate in Cypher, but that's my subjective preference and bias. Neo4j folks: feel free to close if you prefer! |
added the team-clg label Jul 14, 2017
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment
Cypher is a declarative graph query language that allows for expressive and efficient querying and updating of a property graph. Cypher is a relatively simple but still very powerful language. Very complicated database queries can easily be expressed through Cypher. This allows users to focus on their domain instead of getting lost in database access.[1]
Cypher was largely an invention of Andrés Taylor while working for Neo4j, Inc. (formerly Neo Technology) in 2011.[2] Cypher was originally intended to be used with the graph database Neo4j, but was opened up through the openCypher project in October 2015.[3]
- 1Graph model
Graph model[edit]
Cypher is based on the Property Graph Model, which in addition to the standard graph elements of nodes and edges (which are called relationships in Cypher) adds labels and properties as concepts. Nodes may have zero or more labels, while each relationship has exactly one relationship type.[4] Nodes and relationships also have zero or more properties, where a property is a key-value binding of a string key and some value from the Cypher type system.
Type system[edit]
The Cypher type system includes nodes, relationships, paths, maps, lists, integers, floating-point numbers, booleans, and strings.[5]
Syntax[edit]
Cypher contains a variety of clauses. Among the most common are: MATCH and WHERE. These functions are slightly different than in SQL. MATCH is used for describing the structure of the pattern searched for, primarily based on relationships. WHERE is used to add additional constraints to patterns.[6] For example, the below query will return all movies where an actor named 'Nicole Kidman' has acted, and that were produced before a certain year (sent by parameter):
Cypher additionally contains clauses for writing, updating, and deleting data. CREATE and DELETE are used to create and delete nodes and relationships. SET and REMOVE are used to set values to properties and add labels on nodes. Nodes can only be deleted when they have no other relationships still existing. For example:[6]
Standardization[edit]
With the openCypher project, an effort was started to standardize Cypher as the query language for graph processing. One part of this process is the First openCypher Implementers Meeting (oCIM), which was first announced in December 2016.[7][8]
See also[edit]
- Neo4j, a popular graph database for the Cypher Query Language
- SPARQL, another declarative query language for querying graph data
- Gremlin (programming language), another way to query graph data
References[edit]
- ^'Cypher Introduction'. Neo Technology. Retrieved January 31, 2017.
- ^'Cypher: An Evolving Query Language for Property Graphs'(PDF). Proceedings of the 2018 International Conference on Management of Data. ACM. Retrieved June 27, 2018.
- ^'Meet openCypher: The SQL for Graphs - Neo4j Graph Database'. Neo4j Graph Database. 2015-10-21. Retrieved 2017-01-31.
- ^'Property Graph Model'. GitHub. Retrieved 2017-01-31.
- ^'Cypher Type System'. GitHub. Retrieved 2017-01-31.
- ^ ab'Neo4j 3.1.1 manual - MATCH clause'. Neo Technology. Retrieved January 31, 2017.
- ^'openCypher Implementers Meeting · openCypher.org'. www.opencypher.org. Retrieved 2017-01-31.
- ^'oCIM announcement on openCypher Google Groups'. groups.google.com. Retrieved 2017-01-31.
Retrieved from 'https://en.wikipedia.org/w/index.php?title=Cypher_Query_Language&oldid=897590966'