BangDB Graph supports Geospatial hashing-based indexing. Which means we can add latitude, longitude pairs for set of entities and then query for various entities within given Radius or Quadrants etc. For example, some of the queries related to "Near me …", "within radius of 2KM from a point or an entity …" etc. can be answered easily.

Create Geospatial Index

Now, before we add entities and relations, we must create the geoindex for the Graph. Since different entities can have latitude and longitude and their names could be different too. Therefore, we must tell DB about the entity and their latitude, longitude pair. We can do this by issuing following command from CLI. Or from Ampere using the UI Add Index icon

The syntax of the command is as follows:

create geoindex <Graph_Name>.<Entity_Name> = <latitude_attribute_name>.<longitude_attribute_name>

Let's see some of these examples in action.

Example 1

Finding persons near a given person, who is connected with others with some specific relation.

CREATE GRAPH gh1
create geoindex gh1.Person latlon = lat.lon
create geoindex gh1.Company latlon = lat.lon
CREATE (Person:john {"lat":12.8025,"lon":77.4028})-[WORKS_AT]->(Company:Acme {"lat":12.8016,"lon":77.3937})

CREATE (Person:dan {"lat":12.8025,"lon":77.7599})-[WORKS_AT]->(Company:google {"lat":12.8444,"lon":77.5986})

CREATE (Person:mike {"lat":12.8146,"lon":77.6656})-[WORKS_AT]->(Company:Acme {"lat":12.8417,"lon":77.7577})

CREATE (Person:peter {"lat":12.8153,"lon":77.7010})-[WORKS_AT]->(Company:Acme {"lat":12.8543,"lon":77.5882})

CREATE (Person:susan {"lat":12.8187,"lon":77.4169})-[WORKS_AT]->(Company:Acme {"lat":12.8554,"lon":77.5265})

CREATE (Person:andrea {"lat":12.8235,"lon":77.5262})-[WORKS_AT]->(Company:Acme {"lat":12.8585,"lon":77.6706})

CREATE (Person:arti {"lat":12.8281,"lon":77.6464})-[WORKS_AT]->(Company:Acme {"lat":12.8610,"lon":77.5350})

CREATE (Person:teresa {"lat":12.8316,"lon":77.4727})-[WORKS_AT]->(Company:Acme {"lat":12.8696,"lon":77.5991})
S=>(@p Person:john)-[#RADIUS_OF 1000 WORKS_AT]->(@c Company:*)
+-----------+--------+------------+
|sub        |pred    |         obj|
+-----------+--------+------------+
|Person:john|WORKS_AT|Company:Acme|
+-----------+--------+------------+
S=>(@p Person:john)-[@r #RADIUS_OF 1000 WORKS_AT]->(@c Company:*); RETURN p.name AS person, r.rel AS works_at, c.name AS company
+-------+------+--------+
|company|person|works_at|
+-------+------+--------+
|Acme   |john  |WORKS_AT|
+-------+------+--------+
S=>(@p Person:john)-[#RADIUS_OF 1000 WORKS_AT]->(@c Company:*); RETURN COUNT(c.name) AS Num_companies
+-------------+
|Num_companies|
+-------------+
|1            |
+-------------+

Example 2

Entities with no relationships, and finding based on geo-loc solely

CREATE GRAPH gh2
create geoindex gh2.Person latlon = lat.lon
CREATE (Person:john {"lat":12.8025,"lon":77.4028})

CREATE (Person:laila {"lat":12.8015,"lon":77.4022})

CREATE (Person:madlin {"lat":12.8021,"lon":77.4022})

CREATE (Person:rachel {"lat":12.8022,"lon":77.4023})

CREATE (Person:shiela {"lat":12.8020,"lon":77.4020})

CREATE (Person:amelia {"lat":12.8017,"lon":77.4013})

CREATE (Person:paulin {"lat":12.8023,"lon":77.4029})

CREATE (Person:melinda {"lat":12.8011,"lon":77.4019})

Number of people living within radius of 3000m from John

S=>(@p Person:john)-[#RADIUS_OF 3000 *]->(@c *); RETURN COUNT(c.name) AS Num_places
+----------+
|Num_places|
+----------+
|8         |
+----------+

Example 3

Chained query. In these kinds of query, we would like to figure out some nearby entities, and then find some other related entities using some relation and filter.

CREATE GRAPH gh3
create geoindex gh3.Person latlon = lat.lon
create geoindex gh3.Theater latlon = lat.lon
CREATE (Person:john {"lat":12.8025,"lon":77.4028})

CREATE (Theater:regent {"lat":12.8015,"lon":77.4022, "rating":3.9})-[RUNNING_PLAY]->(Play:"Romeo and Juliet" {"likes":81})

CREATE (Theater:veena {"lat":12.8021,"lon":77.4022, "rating":4.3})-[RUNNING_PLAY]->(Play:"Merchant of Venice" {"likes":88})

CREATE (Theater:mona {"lat":12.8022,"lon":77.4023, "rating":4.1})-[RUNNING_PLAY]->(Play:"ABC Murder" {"likes":71})

CREATE (Theater:ashok {"lat":12.8020,"lon":77.4020, "rating":3.6})-[RUNNING_PLAY]->(Play:"ABC Murder" {"likes":97})

Find a Theater(s) within 3KM from person john, which has rating equal to or more than 4.1 and running the play "ABC Murder"

S=>(@p Person:john)-[#RADIUS_OF 3000 *]->(@c Theater:* {rating >= 4.1})-[@r RUNNING_PLAY]->(@pl Play:"ABC Murder"); RETURN c.name AS Theater
+-------+
|Theater|
+-------+
|mona   |
+-------+

Find the theatre with more than 4.1 likes and is within 3Km from john, which is running some play which has more than 80 likes.

S=>(@p Person:john)-[#RADIUS_OF 3000 *]->(@c Theater:* {rating >= 4.1})-[@r RUNNING_PLAY]->(@pl Play:* {likes > 80}); RETURN c.name AS Theater, pl.name AS Play
+------------------+-------+
|Play              |Theater|
+------------------+-------+
|Merchant of Venice|veena  |
+------------------+-------+