MeidokonWiki:

Nebula seems like a decent fit, but getting started with it is a bit tricky, and there's a lot of outdated docs floating around.

While it has a proper large-scale architecture, I want to just use it on my workstation for now, so I'll use the docker-compose method.

Start the database

I don't think this has persistence, so expect to redo all your work if you the workstation is shutdown. I don't know for sure, because I've never used docker-compose before.

These docs are old but they work fine to get it up and running: https://docs.nebula-graph.io/2.0/2.quick-start/2.deploy-nebula-graph-with-docker-compose/

Connect to the console

docker run --rm -it --network nebula-docker-compose_nebula-net --entrypoint=/bin/sh vesoft/nebula-console:v2-nightly

/ # nebula-console -addr graphd -port 9669 -u root -p nebula

This is like a mysql/psql shell now. :QUIT to exit.

Make some structure

I'm using this series of videos: https://www.youtube.com/watch?v=qF4ZhDEN30k&list=PL4ArMmsAnb84uB2d9L46eXpIi7Epz2cfp&index=3

The syntax has changed a little since then though, here's the reference: https://docs.nebula-graph.io/3.2.0/3.ngql-guide/9.space-statements/1.create-space/

(root@nebula) [(none)]> CREATE SPACE mneme (vid_type = int64);
Execution succeeded (time spent 1229/1435 us)

(root@nebula) [(none)]> USE mneme;

(root@nebula) [mneme]> CREATE TAG person (displayname string NOT NULL, dob_year INT, dob_month INT, dob_day INT) comment = 'A single identifiable person, who may have multiple handles/names';

(root@nebula) [mneme]> CREATE TAG handle (name STRING NOT NULL, context STRING, url STRING) comment = 'A name that a Person is known by, in a specific context or situation';

(root@nebula) [mneme]> CREATE TAG photoshoot(shoot_date DATE NOT NULL, shoot_name STRING);

(root@nebula) [mneme]> CREATE EDGE did_shoot(role STRING);

(root@nebula) [mneme]> CREATE TAG location(name STRING, coords GEOGRAPHY) comment = 'Usually a LatLong of a point, but could be a linestring or polygon';

(root@nebula) [mneme]> CREATE EDGE shot_at();

(root@nebula) [mneme]> CREATE EDGE known_as();

Create some data

INSERT VERTEX person(displayname, dob_year, dob_month, dob_day) VALUES 1:("Barney Desmond", 1989, 12, 13);
INSERT VERTEX handle(name) VALUES 2:("furinkan");
INSERT EDGE known_as() VALUES 1 -> 2:();

INSERT VERTEX person(displayname) VALUES 3:("Victoria Ho");
INSERT VERTEX handle(name) VALUES 4:("dboomer");
INSERT EDGE known_as() VALUES 3 -> 4:();

INSERT VERTEX person(displayname) VALUES 5:("Jessica Li");
INSERT VERTEX handle(name, context, url) VALUES 6:("Kisara Shimada", "Facebook", "https://www.facebook.com/kisarawastaken");
INSERT VERTEX handle(name, context, url) VALUES 7:("aerithxzack", "Instagram", "https://www.instagram.com/aerithxzack/");
INSERT VERTEX handle(name, context, url) VALUES 8:("Kisa_9225", "Twitter", "https://twitter.com/Kisa_9225");

// these could be a single INSERT, that's fine too
INSERT EDGE known_as() VALUES 5 -> 6:() ;
INSERT EDGE known_as() VALUES 5 -> 7:() ;
INSERT EDGE known_as() VALUES 5 -> 8:() ;

Now with some masking

INSERT VERTEX handle(name) VALUES 9:("Valerious");
// Yes it really is in longitude-latitude order >:(
INSERT VERTEX location(name, coords) VALUES 10:("International Convention Centre Sydney", ST_GeogFromText("POINT(151.199 -33.8734)"));
INSERT VERTEX photoshoot(shoot_date, shoot_name) VALUES 11:(date("2020-03-08"), "Madman Anime Festival");

INSERT VERTEX handle(name) VALUES 12:("shortgirls.net");
INSERT EDGE known_as() VALUES 1 -> 12:();

INSERT EDGE shot_at() VALUES 11 -> 10:() ;
INSERT EDGE did_shoot(role) VALUES 9 -> 11:("cosplayer") ;
INSERT EDGE did_shoot(role) VALUES 12 -> 11:("photographer") ;

Valerious is a cosplayer, but she doesn't have a Person associated with her. As demonstrated here:

(root@nebula) [mneme]> GO FROM 11 OVER did_shoot REVERSELY YIELD properties($$).name AS participant;
+------------------+
| participant      |
+------------------+
| "Valerious"      |
| "shortgirls.net" |
+------------------+

// Now try and map that back to a real person
> GO FROM 11     OVER did_shoot REVERSELY YIELD did_shoot._dst as hid | \
  GO FROM $-.hid OVER known_as REVERSELY YIELD $^.handle.name AS handle, properties($$).displayname AS person_name;
+------------------+------------------+
| handle           | person_name      |
+------------------+------------------+
| "shortgirls.net" | "Barney Desmond" |
+------------------+------------------+

Those special variables ($$ and $- and $^) are Operators.

Inspect it with the studio

The Studio is basically a nice web-enabled console.

docker pull vesoft/nebula-graph-studio:v3.4.0

docker run -d -it -p 7001:7001 vesoft/nebula-graph-studio:v3.4.0

Hit it on http://localhost:7001/

You can connect with:

Python client

https://github.com/vesoft-inc/nebula-python##How-to-choose-nebula-python

Activate your venv and then install the client library. I'm using Nebula 3.4, but the latest client is 3.1.0

pip install nebula3-python==3.1.0

Then this is the easiest way to use it.

>>> from nebula3.gclient.net import ConnectionPool
>>> from nebula3.Config import Config
>>> 
>>> # define a config
>>> config = Config()
>>> config.max_connection_pool_size = 10
>>> # init connection pool
>>> connection_pool = ConnectionPool()
>>> # if the given servers are ok, return true, else return false
>>> ok = connection_pool.init([('127.0.0.1', 9669)], config)
>>> 
>>> ok
True
>>> session = connection_pool.get_session('root', 'nebula')
>>> session.execute('USE mneme')
ResultSet(None)
>>> session.execute('SHOW TAGS')
ResultSet(keys: ['Name'], values: ["handle"],["location"],["person"],["photoshoot"])


>>> from pprint import pprint as PP
>>> r = session.execute('''GO FROM 5 OVER known_as YIELD $^.person.displayname AS person, $$.handle.name AS handle;''')
>>> ks = r.keys()

>>> PP([ dict(zip(ks, [x.value.decode('utf8') for x in row.values])) for row in r.rows() ])
[{'handle': 'Kisara Shimada', 'person': 'Jessica Li'},
 {'handle': 'aerithxzack', 'person': 'Jessica Li'},
 {'handle': 'Kisa_9225', 'person': 'Jessica Li'}]

MeidokonWiki: furinkan/Mneme/NebulaGraph (last edited 2022-07-31 18:56:46 by furinkan)