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