cancel
Showing results forΒ
Did you mean:Β

## Searching for all nodes with same property of Match

Node Clone

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...?

1 ACCEPTED SOLUTION
Ninja

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?β

any(x in ntypes where x in types)

@Cobra thanks for the tip.

12 REPLIES 12
Ninja

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

I think that should work.

Node Clone

THANK YOU! This worked great!

Node Clone

To be 100% Clear, This is the goal:

I believe that I originally had the `WHERE all(t IN ntypes WHERE t in types)` in the wrong order. Does this make sense? I believe it should be:

WHERE all(t IN types WHERE t in ntypes)

Ninja

Hello @aaron.damiano

What is the format of the property `type`? A string or a list? Can you share an example?

Regards,
Cobra

Node Clone

1 String
"Blouse", "Sweater","Bikini top"

Ninja

So each Product has only 1 type? The string only represent one type?

Node Clone

YES, each product has 1 type represented by 1 string.

Ninja

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.

Node Clone

@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.

Ninja

Oh yeah indeed, let @glilienfield write the final query and you could accept it as an answer.

P.S: @glilienfield, you can use ``` before and after your code to make it easier to read and to copy paste π

Ninja

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?β

any(x in ntypes where x in types)

@Cobra thanks for the tip.

Nodes 2022

NODES 2022, Neo4j Online Education Summit

OnΒ November 16 and 17 for 24 hours across all timezones, youβll learn about best practices for beginners and experts alike.

Neo4j Resources