Geo location

What I want to do

I am new to Dgraph. I am using GraphQL api. I have a type Trait node that I want to be able to have either a point or polygon predicate (indexed for searches/filters). This trait is related to a Brand, so should these coordinates. I am confused as to whether Point and Polygon are scalar types (as I used in the below schema) or are node types that have to be predefined as per

(why are there no ID’s defined?)

Q. If I have to predefine the nodes as per link above, how do I make sure that specific points/poly/multipolygon’s are separated by Brand, ie: 2 brands could have the same point but they are unrelated. Moreover, in a near search only brand specific points are searched. In this database there could be 1000 different brands all with their own geo locations.

What I did

type Trait{
id: ID!
brand: Brand! @hasInverse(field: traits)
name: String! @search(by: [regexp])
geo_location: Boolean
location_point: Point @search
location_polygon: Polygon @search
order: Int # what listing order 1 = 1st
}

Dgraph metadata

using dgraph cloud

Thanks for the help!

Geolocation types are scalar in the sense that your location_point could be duplicated for many Trait objects (not referenced)… in the same way and integer or a string could be duplicated in the graph. In other words, there is no unique identifier associated with a Point or Polygon.

2 things:

  1. Just to confirm: Point is not scalar by itself, ie: I would need to have already defined

type Point {
longitude: Float!
latitude: Float!
}
2. Can I add any other predicates, relationships to type Point and it still work/function as Geo?
eg.
type Point {
longitude: Float!
latitude: Float!
brand: Brand! @hasInverse (field:geo_point)
}
3. If #2 is not possible how do I maintain separate Points per Brand? Can I do a search with filter on Trait by brand so only those brand trait points are used for a near search?

Not sure why you’d want to re-define Point. Maybe I’m not grokking what you’re asking.

Do you really need to do this? Maybe let’s back up and discuss how you’re looking to search. It seems that one query you’d like to make is: “what Brands are near a particular location?”. If so:

query {
  queryBrand (filter: { location_point: { near: { coordinate: { latitude: 37.771935, longitude: -122.469829 }, distance: 1000 } } }) {
    id
  }
}

Dgraph auto-generates a GraphQL API for your schema, when it sees a Point predicate within a type, it adds the special near, within, etc fields in the filter type associated with the object’s query endpoint.

Make sense?

The Dgraph reference link above would seem to indicate that Point needs to be defined first as a type. If it doesn’t, and I can define a predicate location_point: Point @search and it automatically knows it is a longitude, latitude, then that’s what I was wanting to confirm. (which should then allow for below)

For each Brand there are many Traits which all have Points. When I am doing a near search it needs to be constrained to only searching the Trait Points of the specific Brand. There will be many Brands, each brand’s locations are not related to another brand and so an near searches need to stay within the brand. The near search then finds the Traits of the Brand that are near the specified location.

In that case, a search similar to this should do the trick:

query {
  queryBrand(filter: {name: {eq: "Acme"}}) @cascade {
    traits(filter: {point_location: {near: {distance: 1000, coordinate: {longitude: -122.469829, latitude: 37.771935}}}})
  }
}

1 Like

Perfect, Thanks!