jamesfer / cypher-query-builder

An flexible and intuitive query builder for Neo4j and Cypher.
http://jamesfer.me/cypher-query-builder/index.html
MIT License
105 stars 22 forks source link

Behaviour of where operators is inconsistent #99

Open jamesfer opened 5 years ago

jamesfer commented 5 years ago

According to the where operator types xor and or must accept an array of NodeConditions, Conditions or a single Condition.

This means you can do things like

query.where({
  age: xor([greaterThan(65), lessThan(12)]),
})

However, the and operator only accepts NodeConditions or Conditions. So you wouldn't be able to do the same thing.

I think and should be able to accept a Condition argument, which means that it probably needs to accept array properties as well. To make things entirely consistent, we should consider make all operators accept AnyConditions and then just use the operator to combine the outer most structure so:

query.where({ age: and([lessThan(65), greaterThan(12)])
// becomes
// WHERE age < 65 AND age > 12

query.where({ department: or({ inactive: true, members: 0 }) })
// becomes
// WHERE department.inactive = true OR department.members = 0

This shouldn't be a breaking change because previously the types limited what constructs could be supplied to each operator so this would technically be an expanding of functionality, but I would need to double check because maybe the code accepted all types to each function anyway which would mean that some javascript code may already be relying on old unsupported behaviour.

This is related to #14 and should probably be implemented together (unless this issue is breaking then #14 should be released soon and this deferred until 5.0).

kalzoo commented 4 years ago

yup, just ran into this:

    const query = new Query().where({
      name: and([comparisons.contains("abc"), comparisons.lessThan("x")])
    });

=>

    { query: 'WHERE name.0 CONTAINS $ AND name.1 < $2;',
      params: { '2': 'x', '': 'abc' } }

Of course the most common use case (and the one in your example) is handled by between, which is great. It would be "nice" to be able to combine these operators, but it's a narrow use case.

Thanks for your great work on this library! I'm using it as the basis for a personal project I'd like to be able to open-source soon. Would not have made it anywhere as far without cypher-query-builder.