Hi, I have a product <values> attributeOption
relation.
Now I am trying to find all products having a values edge and fulfil this filter:
$and: [$in:{attributeOption.id, [10, 20]}, $in:{attributeOption.id, [30, 40]}]
Here is how I would do it in SQL with n-m relationship:
SELECT count(*) from "products"
join "productValues" as v1 on "v1"."productId" = "products"."id" and "v1"."optionId" in (10, 20)
join "productValues" as v2 on "v2"."productId" = "products"."id" and "v2"."optionId" in (30, 40)
How can I do this in Dgraph ? Thanks!
{
"type": "product",
"id": 1,
"label": "Computer",
"values": [
{
"type": "AttributeOption",
"id": 20,
"label": "Dell"
},
{
"type": "AttributeOption",
"id": 30,
"label": "HP"
},
{
"type": "AttributeOption",
"id": 40,
"label": "20Gb"
},
{
"type": "AttributeOption",
"id": 50,
"label": "40Gb"
}
]
}
MichelDiz
(Michel Diz)
January 11, 2020, 4:44pm
2
Something like this?
{
q(func: eq(label, "Computer")){
id
label
values @filter(eq(id, ["10", "20", "30", "40"])) {
id
label
}
}
}
MichelDiz:
Something like this?
That was my first guess too but it’s not quite what I am looking for. Because it returns products that don’t match the filter.
Assuming this is my source:
const test = [
{
type: "product",
id: 1,
label: "Computer 1",
values: [
{
type: "AttributeOption",
id: 20,
label: "Dell"
},
{
type: "AttributeOption",
id: 40,
label: "20Gb"
}
]
},
{
type: "product",
id: 2,
label: "Computer 2",
values: [
{
type: "AttributeOption",
id: 30,
label: "HP"
},
{
type: "AttributeOption",
id: 40,
label: "20Gb"
}
]
}
]
I want to run two queres:
eq(type, ‘product’) and eq(values.id, [20, 30]) and eq(values.id, [40]) => this should return both products
eq(type, ‘product’) and eq(values.id, [30]) and eq(values.id, [40]) => this should return product with id 2
Anurag
(Anurag)
July 8, 2020, 4:20pm
4
Hi @johnson , apologies for the delay. I hope you find this useful still.
Schema
id: int .
label: string .
values: [uid] @reverse .
type Product {
id: int
label: string
values: [uid]
}
type AttributeOption {
id: int
label: string
}
Data
<1> <id> "1" .
<1> <label> "Computer 1" .
<1> <dgraph.type> "Product" .
<2> <id> "2" .
<2> <label> "Computer 2" .
<2> <dgraph.type> "Product" .
<3> <id> "20" .
<3> <label> "Dell" .
<3> <dgraph.type> "AttributeOption" .
<4> <id> "40" .
<4> <label> "20GB" .
<4> <dgraph.type> "AttributeOption" .
<5> <id> "30" .
<5> <label> "HP" .
<5> <dgraph.type> "AttributeOption" .
<1> <values> <3> .
<1> <values> <4> .
<2> <values> <5> .
<2> <values> <4> .
Queries:
For the first query, you can go with the below:
query{
var(func: type(Product) ){
v1 as values @filter( lt(id, 30) AND gt(id, 20) )
}
var(func: type(Product) ){
v2 as values @filter( eq(id, 40) )
}
q(func: uid(v1, v2)){
~values{
id
label
}
}
}
Edit: On looking closely at this, the above query works but that is more accidental. Taking a closer look.
MichelDiz
(Michel Diz)
July 9, 2020, 8:00pm
10
Okay, Taking Anurag’s sample I have found the following.
johnson:
eq(type, ‘product’) and eq(values.id, [20, 30]) and eq(values.id, [40]) => this should return both products
query
query{
G as var(func: type(Product) )
G1 as var(func: uid(G) ) @cascade {
values @filter(eq(id, "40"))
}
G2 as var(func: uid(G) ) @cascade {
values @filter(eq(id, "30", "20"))
}
q(func: uid(G1, G2) ) {
uid
label
}
}
Return
{
"data": {
"q": [
{
"uid": "0x1",
"label": "Computer 1"
},
{
"uid": "0x2",
"label": "Computer 2"
}
]
}
}
johnson:
eq(type, ‘product’) and eq(values.id, [30]) and eq(values.id, [40]) => this should return product with id 2
query
query{
G as var(func: type(Product) )
q(func: uid(G) ) @cascade {
uid
label
id
values @filter( eq(id, "40", "30"))
}
}
Return
{
"data": {
"q": [
{
"uid": "0x2",
"label": "Computer 2",
"id": 2
}
]
}
}
2 Likes
Anurag
(Anurag)
July 9, 2020, 8:29pm
11
Didn’t know cascade
could be used for child nodes as well, I thought only for scalar predicates. Great work! I learn so much from you @MichelDiz !
1 Like