I am trying to find ALL other Customers who purchased products with ALL the same TYPE properties as C.
MATCH (c:customer{customer_id: '00006413d8573cd20ed7128e53b7b13819fe5cfc2d801fe7fc0f26dd8d65a85a'})-[]->(p:product)
WITH c, COLLECT(DISTINCT p.type) as types
MATCH (nc:customer)-[]->(np:product)
WHERE all(t IN np.type WHERE t.type in types)
RETURN DISTINCT c
I am getting this error:
Type mismatch: expected a map but was String("Vest top")
types is an array of Strings ["Vest top", "Pants",....] but I so should be np.type...?
The value of np.type in the WHERE clause is a scalar; it needs to be a list. The following query should return the other customers who's purchased products all have the same product type as the customer.
MATCH (c:customer{customer_id: '00006413d8573cd20ed7128e53b7b13819fe5cfc2d801fe7fc0f26dd8d65a85a'})-->(p:product)
WITH COLLECT(DISTINCT p.type) as types
MATCH (nc:customer)-->(np:product)
WITH types, nc, collect(np.type) as ntypes
WHERE all(t IN ntypes WHERE t in types)
RETURN DISTINCT nc
Note, the above query allows the customer to have purchased more product types than the other customers. It only restricts the other customers to have their products be within the set of product types defined by the provided customer. If you want the customer and the other customer to have exactly the same set of property types, i.e. no more nor no less, then we can add one additional constraint.
MATCH (c:customer{customer_id: '00006413d8573cd20ed7128e53b7b13819fe5cfc2d801fe7fc0f26dd8d65a85a'})-->(p:product)
WITH COLLECT(DISTINCT p.type) as types
MATCH (nc:customer)-->(np:product)
WITH types, nc, collect(np.type) as ntypes
WHERE size(types) = size(ntypes)
AND all(t IN ntypes WHERE t in types)
RETURN DISTINCT nc
The query of @glilienfield is good so what is the issue? Your first query cannot work since you need to collect types for each customer to then compare them with the one you want.
@glilienfield solved the original issue of the error.
However, when I ran the query I got:
I reversed the "WHERE all" statement and got the desired answer:
WHERE all(t IN types WHERE t in ntypes )
*I want to make sure that this post's final answer is what I was trying to achieve so that if anyone else reads in the future they get the output they expect.
Yes in deed, the order does matter. Given two sets A and B, the following predicate determines if A is a subset of B:
all(x in A where x in B),
As it tests each element of A to determine if it is in B. B can be larger and the predicate is still true.
Reversing the order determines if B is a subset of A
If you want equality, then add the constraint that the size of each is equal.
Your original post stated âother customers that purchased all of the customerâs product types.â This sounds like other customerâs product types have to be a subset of the customerâs, which the query represents.
In reality, you want the other customers who purchased at least all of the customerâs product types. This implies the customerâs product types needs to be a subset of the other customerâs product types. So yes, you are correct. The query needs to test that each element in the customerâs list is in the other customerâs list.
MATCH (c:customer{customer_id: '00006413d8573cd20ed7128e53b7b13819fe5cfc2d801fe7fc0f26dd8d65a85a'})-->(p:product)
WITH COLLECT(DISTINCT p.type) as types
MATCH (nc:customer)-->(np:product)
WITH types, nc, collect(np.type) as ntypes
WHERE all(t in types WHERE t in ntypes)
RETURN DISTINCT nc
Btw- the graph on the right of âwhat you gotâ doesnât seem to be a result of the first query, as there are circles representing the other customers that have elements not in the customerâs set. That looks more like the result of the following predicate. The equivalent of âdo they intersect?â