How to get distinct nodes

example

(sivakarna) #1

Hi
How to get distinct nodes

i have a flow like this

uid A B C D
orangegroup --> Country -state-> State -district-> District -city-> City
uid C D
greengroup --> District -city-> City

from above two groups when we combined need only distinct nodes

        uid              A ->B ->C ->D
 (orangegroup,greengroup)  -> Country  -state->  State -district-> District     -city->       City

I have tried using variable ,but duplicate results comming


(Michel Conrado (Support Engineer)) #2

Through your example I can not get a sense of the problem. I can imagine several things,
but not something concrete. Could you generate a small example in JSON obj?
and tell which Queries you are using.

Just a little bit of context to help us to help you.

Cheers.


(sivakarna) #3

Hi

Following is the mutation set

 #Group Meta Data
    _:orangegroup <Name> "Orange" .
	_:orangegroup <Type> "Group" .
	
    _:greengroup <Name> "Green" .
	_:greengroup <Type> "Group" .
	
	_:District <Name> "Ind" .
	_:District <Type> "District" .
	
  _:Area <Name> "TS" .
	_:Area <Type> "Area" .
	
	_:Field <Name> "Hyd" .
    _:Field <Type> "Field" .
	
	_:Location <Name> "gachibowli" .
    _:Location <Type> "Location" .
	
	
	#RelationShip
	
	_:District <area> _:Area .
	_:Area  <field> _:Field .
	_:Field <location> _:Location .
	
	
	_:orangegroup <entityLink> _:District .
	_:greengroup <entityLink> _:Field .

From The Above,If i combine (:orangegroup,:greengroup) result should be

{
_:District :{
_:area{
_:field{
_:location{
}
}
}
}
}

I am usisng this query to get the result


{
  
  var(func:eq(Type,Group)){
    entitiesorange As entityLink{
      Name
    }
  }
   var(func:eq(Type,Group)){
    entitiesgreen As entityLink{
      Name
    }
  }
    
  entities(func:uid(entitiesorange,entitiesgreen))@recurse(depth:4){
    Name
    Type
    area{
      Name  
      Type
    }
    field{
      Name
      Type
    }
    location{
      Name
      Type
    }
  }
}

and out put comming as like this

{
    "entities": [
      {
        "Name": "Ind",
        "Type": "District",
        "area": [
          {
            "Name": "TS",
            "Type": "Area",
            "field": [
              {
                "Name": "Hyd",
                "Type": "Field",
                "uid": "0x29830"
              }
            ],
            "uid": "0x2982f"
          }
        ],
        "uid": "0x2982e"
      },
      {
        "Name": "Hyd",
        "Type": "Field",
        "location": [
          {
            "Name": "gachibowli",
            "Type": "Location",
            "uid": "0x29831"
          }
        ],
        "uid": "0x29830"
      }
    ]
  }

(Michel Conrado (Support Engineer)) #4

I still don’t get what you wanna to do exac.

Your example seems incompatible with the idea.
The Orange don’t have “location”. And your query is doing nothing, has no effect.
In fact the variables are collecting the same graph objects/nodes. You don’t have any
filter there.

There’s no way in Dgraph to combine something by no similarity, via values.
something possible would be something like this https://tour.dgraph.io/search/4/
or work with nodes relations by edges and reverse edges.

your data:

{
  "data": {
    "q": [
      {
        "uid": "0xfb771",
        "Type": "Group",
        "Name": "Orange",
        "entityLink": [
          {
            "uid": "0xfb773",
            "Type": "District",
            "Name": "Ind",
            "area": [
              {
                "uid": "0xfb774",
                "field": [
                  {
                    "uid": "0xfb775",
                    "Type": "Field",
                    "Name": "Hyd"
                  }
                ],
                "Type": "Area",
                "Name": "TS"
              }
            ]
          }
        ]
      }
    ],
    "q2": [
      {
        "uid": "0xfb772",
        "Type": "Group",
        "Name": "Green",
        "entityLink": [
          {
            "uid": "0xfb775",
            "Type": "Field",
            "Name": "Hyd",
            "location": [
              {
                "uid": "0xfb776",
                "Type": "Location",
                "Name": "gachibowli"
              }
            ]
          }
        ]
      }
    ]
  }

(Michel Conrado (Support Engineer)) #5

Check this if it helps.

PS. If “getTrueOne” block is empty, there are no relations in entities

{
  
  var(func:eq(Name, "Orange")){
    entitiesorange As entityLink
  }
   var(func:eq(Name, "Green")){
    entitiesgreen As entityLink
  }
    
  entities(func:uid(entitiesorange, entitiesgreen))@recurse(depth:5){
    uid
    Type
    Name
    area
    #This filter will return if one of those nodes with "field" were true
    #If a node doesn't have the predicate "field" this variable will be
    #empty. So between "Orange" and "Green" - one will be true.
    #So you will know that the "Hyd Field" exists in both
   gettheone as field @filter(uid(entitiesorange, entitiesgreen))
    location
  }
}
    
   {
  getTrueOne(func: uid(gettheone)){
    uid
    expand(_all_){uid expand(_all_)}
  } 
  }

Data


{
  "data": {
    "entities": [
      {
        "uid": "0xfb773",
        "Type": "District",
        "Name": "Ind",
        "area": [
          {
            "uid": "0xfb774",
            "Type": "Area",
            "Name": "TS",
            "field": [
              {
                "uid": "0xfb775",
                "Type": "Field",
                "Name": "Hyd"
              }
            ]
          }
        ]
      },
      {
        "uid": "0xfb775",
        "Type": "Field",
        "Name": "Hyd",
        "location": [
          {
            "uid": "0xfb776",
            "Type": "Location",
            "Name": "gachibowli"
          }
        ]
      }
    ],
    "getTrueOne": [
      {
        "uid": "0xfb775",
        "Type": "Field",
        "Name": "Hyd",
        "location": [
          {
            "uid": "0xfb776",
            "Type": "Location",
            "Name": "gachibowli"
          }
        ]
      }
    ]
  }

Example when false

{
  var(func:eq(Name, "Orange")){
    entitiesorange As entityLink
  }
   var(func:eq(Name, "Green")){
    entitiesgreen As entityLink
  }
    
  entities(func:uid(entitiesorange, entitiesgreen))@recurse(depth:5){
    uid
    Type
    Name
    area
   gettheone as field @filter(uid(entitiesorange))
    location
  }
}
    
   {
  getTrueOne(func: uid(gettheone)){
    uid
    expand(_all_){uid expand(_all_)}
  } 
  }
{
  "data": {
    "entities": [
      {
        "uid": "0xfb773",
        "Type": "District",
        "Name": "Ind",
        "area": [
          {
            "uid": "0xfb774",
            "Type": "Area",
            "Name": "TS"
          }
        ]
      },
      {
        "uid": "0xfb775",
        "Type": "Field",
        "Name": "Hyd",
        "location": [
          {
            "uid": "0xfb776",
            "Type": "Location",
            "Name": "gachibowli"
          }
        ]
      }
    ],
    "getTrueOne": [] #So it's false.
  }

(sivakarna) #6

Hi Thanks for your efforts

Actually what i need to do is

we have an application to show the nodes in an hairachy level(district-area-field-location) to the user based on his groups which are all connected to the nodes

Hairachy Nodes:

{
   "Name":"HydDist",
   "uid" : "01D"
   "areaLink":{
     Name:"HydArea",
	 "uid":"01A",
	 "fieldLink":{
	  "Name":"HydField",
	  "uid":"01F",
	  "locationLink":{
	    "Name":"HydLocation",
		"uid":"01L"
	  }
	   
	 }
    }
   }

so assume person have onegroup called orangegroup node which is connected to the top node district ,so final relationship will be

{
   "Name":"orangegroup",
   "uid" : "01OG",
   "entitylink":{
   "Name":"HydDist",
   "uid" : "01D"
   "areaLink":{
     Name:"HydArea",
	 "uid":"01A",
	 "fieldLink":{
	  "Name":"HydField",
	  "uid":"01F",
	  "locationLink":{
	    "Name":"HydLocation",
		"uid":"01L"
	  }
	   
	 }
    }
   }
}

so when i query i can get the same hirachy which i want district-area-field-location

{
   "Name":"HydDist",
   "uid" : "01D"
   "areaLink":{
     Name:"HydArea",
	 "uid":"01A",
	 "fieldLink":{
	  "Name":"HydField",
	  "uid":"01F",
	  "locationLink":{
	    "Name":"HydLocation",
		"uid":"01L"
	  }
	   
	 }
    }
   }

now assume same person have another group called greengroup and its connected as follows

{
   "Name":"greengroup",
   "uid" : "01GG",
   "entitylink":{
	  "Name":"HydField",
	  "uid":"01F",
	  "locationLink":{
	    "Name":"HydLocation",
		"uid":"01L"
	  }
	   
	}
}

so when i query again for the same person i need to get the same hairachy with out duplicate nodes
district - area - field - location

person ->(orangegroup,greengroup) :

{
   "Name":"HydDist",
   "uid" : "01D"
   "areaLink":{
     Name:"HydArea",
	 "uid":"01A",
	 "fieldLink":{
	  "Name":"HydField",
	  "uid":"01F",
	  "locationLink":{
	    "Name":"HydLocation",
		"uid":"01L"
	  }
	   
	 }
    }
   }

Is that possible ?


(sivakarna) #7

Hairachy Nodes

{
   "Name":"HydDist",
   "uid" : "01D"
   "areaLink":{
     Name:"HydArea",
	 "uid":"01A",
	 "fieldLink":{
	  "Name":"HydField",
	  "uid":"01F",
	  "locationLink":{
	    "Name":"HydLocation",
		"uid":"01L"
	  }
	   
	 }
    }
   }

and if another person contains only one group called green group which is directly connected to field

{
   "Name":"greengroup",
   "uid" : "01GG",
   "entitylink":{
	  "Name":"HydField",
	  "uid":"01F",
	  "locationLink":{
	    "Name":"HydLocation",
		"uid":"01L"
	  }
	   
	}
}

so if i query for this person to show hairachy i need to get for this parents parents of this field

so final result will be

{
   "Name":"HydDist",
   "uid" : "01D"
   "areaLink":{
     Name:"HydArea",
	 "uid":"01A",
	 "fieldLink":{
	  "Name":"HydField",
	  "uid":"01F",
	  "locationLink":{
	    "Name":"HydLocation",
		"uid":"01L"
	  }
	   
	 }
    }
   }

Thanks


(Michel Conrado (Support Engineer)) #8

Do you wanna smash two nodes in one result based on similarities?

If so, Dgraph can’t do that. You should do it in the application level.

Or If you wanna see both data with the same structure you should mutate all of your data with the same structure. The example you gave me has different structures. While one has “location” the other has “field” with the same node. They are distinct in structure. The nodes that they are pointing are the same, but the way you built this structure is incompatible. And Dgraph can’t smash them together to show as you want. They’re in diferente “levels”. Green data has 3 levels, and Orange has 4. And each level use a different hierarchies.

You need to do it via application level. Or maybe I’m wrong and I still do not understand what you want to do.

Your hierarchy is applicable perfectly. But you should keep it the same “format” forever. If you want to use hierarchy as a parameter.