On this page

Geospatial Index and Query

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         |
+----------+
Note: * in relation ([#RADIUS_OF 3000 *]), means that there may be any relation between subject and object or no relation at all

 

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  |
+------------------+-------+

 

 

Was this article helpful to you? Yes No