Filtering based on path traversal


(Siddharth Prakash Singh) #1

Here is a sample mutation -


{
  set {
    _:city <city.name> "Delhi"

    _:neighborhood1 <neighborhood.name> "Lutyens"
    _:neighborhood1 <neighborhood.city> _:city # Reverse edge is available
    _:neighborhood2 <neighborhood.name> "CR Park"
    _:neighborhood2 <neighborhood.city> _:city # Reverse edge is available
    _:neighborhood3 <neighborhood.name> "GK2"
    _:neighborhood3 <neighborhood.city> _:city # Reverse edge is available

    _:lb1A <block.name> "Block A"
    _:lb1A <block.neighborhood> _:neighborhood1 #Reverse edge is available
    _:lb1B <block.name> "Block B"
    _:lb1B <block.neighborhood> _:neighborhood1 #Reverse edge is available
    _:lb1C <block.name> "Block C"
    _:lb1C <block.neighborhood> _:neighborhood1 #Reverse edge is available
    _:lb1D <block.name> "Block D"
    _:lb1D <block.neighborhood> _:neighborhood1 #Reverse edge is available


    _:lb2A <block.name> "Block A"
    _:lb2A <block.neighborhood> _:neighborhood2 #Reverse edge is available
    _:lb2B <block.name> "Block B"
    _:lb2B <block.neighborhood> _:neighborhood2 #Reverse edge is available
    _:lb2C <block.name> "Block C"
    _:lb2C <block.neighborhood> _:neighborhood2 #Reverse edge is available
    _:lb2D <block.name> "Block D"
    _:lb2D <block.neighborhood> _:neighborhood2 #Reverse edge is available

    _:lb3A <block.name> "Block 0"
    _:lb3A <block.neighborhood> _:neighborhood3 #Reverse edge is available


    _:b1A1 <building.number> 100
    _:b1A1 <building.block> _:lb1A #Reverse edge is available
    _:b1B1 <building.number> 101
    _:b1B1 <building.block> _:lb1B #Reverse edge is available

    _:b2A1 <building.number> 110
    _:b2A1 <building.block> _:lb2A
    _:b2C1 <building.number> 111
    _:b2C1 <building.block> _:lb2C'\

    _:apt1 <bhk> "2bhk"
    _:apt1 <apt.building> _:b1A1 # has reverse edge
    _:apt2 <bhk> "2bhk"
    _:apt2 <apt.building> _:b1A1 # has reverse edge
    _:apt3 <bhk> "3bhk"
    _:apt3 <apt.building> _:b1A1 # has reverse edge

    _:apt4 <bhk> "3bhk"
    _:apt4 <apt.building> _:b2A1 # has reverse edge
    _:apt5 <bhk> "2bhk"
    _:apt5 <apt.building> _:b2A1 # has reverse edge
    _:apt6 <bhk> "3bhk"
    _:apt6 <apt.building> _:b2A1 # has reverse edge

  }
}

Now our algorithm says that given an apartment apt1 - all apartments with same bhk in same neighborhood are similar.
In above example apt1 is similar to apt2 but not to apt3
Similarly apt4 is similar to apt6 but not to apt5.

So if the input to graph query is apt1 and apt4, how will I be able to find similar apartments. I couldn’t get a way to filter based on predicate in travel history.


(Siddharth Prakash Singh) #2

Any suggestion please.


(Michel Conrado (Support Engineer)) #3

I can not see anything special, so I believe that two blocks querying “bhk” indexed by EXAC solve the case. But you can always follow your structure as I show below.

If “bhk” is the reference, there is not much to do. Also apt1 and apt4 are in different neighborhoods. So they do not have relationships. As you said “all apartments with same bhk in same neighborhood are similar.” Soon those who are not are not similar.

The only way is to construct a query with two blocks.

Another detail is that your Mutation contains typo errors. I had to reformulate it.

{
  var(func: eq(neighborhood.name, "Lutyens")) {
  ~block.neighborhood {
    ~building.block{
    apts as ~apt.building @filter(eq(bhk, "2bhk"))
  }
  }
}
  
  apartments(func: uid(apts)) {
    expand(_all_)
  }
  
}

Result


{
  "data": {
    "apartments": [
      {
        "bhk": "2bhk",
        "uid": "0x34"
      },
      {
        "bhk": "2bhk",
        "uid": "0x42"
      }
    ]
  }

Other Q

{
  q1(func: eq(bhk, "2bhk")){
    uid
    expand(_all_)
  }
  q2(func: eq(bhk, "3bhk")){
    uid
    expand(_all_)
  }
}

Result

{
  "data": {
    "q1": [
      {
        "uid": "0x34",
        "bhk": "2bhk"
      },
      {
        "uid": "0x3d",
        "bhk": "2bhk"
      },
      {
        "uid": "0x42",
        "bhk": "2bhk"
      }
    ],
    "q2": [
      {
        "uid": "0x35",
        "bhk": "3bhk"
      },
      {
        "uid": "0x3c",
        "bhk": "3bhk"
      },
      {
        "uid": "0x41",
        "bhk": "3bhk"
      }
    ]
  }

(Siddharth Prakash Singh) #4

@MichelDiz Here you are using “2bhk” as hard coded input to query.
I would rather have a list of apartment uid as input and get similar apartments. I get stuck in that situation because using val(scalar_variable) merges all values.


(Michel Conrado (Support Engineer)) #5

As there are no similarities in different things. You must use different blocks. You could use groupby, but the characteristics would have to be identified as Nodes and not attributes of a Node. And would group only by one characteristic.

If you use a single block only you will simply mix all results of apt1 and apt4. To look for similarities in each neighborhood you need to do in different blocks.

Just construct a block for each input with its respective filters.

GroupBy: https://docs.dgraph.io/query-language/#groupby


(Siddharth Prakash Singh) #6

Got it.
So in a way it would be almost impossible if I had to start with a user who has liked n houses and find similar houses which he/she may like?


(Michel Conrado (Support Engineer)) #7

Of course you can. The problem is that you said:

“all apartments with same bhk in same neighborhood are similar.”

apt1 = Lutyens neighborhood
apt4 = CR Park neighborhood

If you had said:

“all apartments with same bhk are similar.”

it would be possible.

But ideally, you break down the features of the apartment into smaller parts within a hierarchical Nodes structure (just like tags). So you can have a greater power of comparison.

if 2bhk(Lutyens) !== 2bhk(CR Park) : There’s nothing to compare.