How to create index on AgensGraph? - agens-graph

When traverse vertex or egde, It is very slow.
I want to create index for accelerating speed.
# match (n:v{id:1}) return n;
n
-----------------
v[3.1]{"id": 1}
(1 row)
Time: 693.100 ms
How can I create index for vertex or edge?

Use "CREATE PROPERTY INDEX" statement for create index on graph object.
# match (n:v{id:1}) return n;
n
-----------------
v[3.1]{"id": 1}
(1 row)
Time: 693.100 ms
# create property index on v ( id );
CREATE PROPERTY INDEX
Time: 2227.147 ms
# match (n:v{id:1}) return n;
n
-----------------
v[3.1]{"id": 1}
(1 row)
Time: 5.935 ms
In this case, accelerated over than hundred times.

Creating Index
agens=> CREATE PROPERTY INDEX ON [VERTEX OR EDGE LABEL] ([PROPERTY])
agens=> CREATE PROPERTY INDEX ON CUSTOMER (AGE)
Creating Unique Index (Allow only one edge between two vertices)
agens=> CREATE UNIQUE INDEX [INDEX NAME] ON [GRAPH_PATH.VERTEX OR EDGE LABEL] ([PROPERTIES])
agens=> CREATE UNIQUE INDEX STUDENT_UNIQ_INDEX ON [AGENS_GRAPH.CUSTOMER] ("start", "end")
Creating Unique Constraint
agens=> CREATE CONSTRAINT ON [VERTEX OR EDGE LABEL] [PROPERTY] IS UNIQUE
agens=> CREATE CONSTRAINT ON CUSTOMER CUSTOMER_ID IS UNIQUE

Related

How to get max location id of label more faster on AgensGraph?

I want to get largest location id of label.
But, It is very slow on follow query.
agens=# match (n:v) return max(graphid_locid(id(n)));
max
-----
6
(1 row)
How to get max location id of label more faster on AgensGraph?
Fetch related sequence value from pg_sequences table.
agens=# select start_value from pg_sequences where schemaname = 'graph' and sequencename = 'v_id_seq';
start_value
-------------
6
(1 row)

How to modify property of label on AgensGraph?

I created new vertex on AgensGraph using CREATE statement.
How can I modify the properties of created vertex?
agens=# create (:v{prop:1});
GRAPH WRITE (INSERT VERTEX 1, INSERT EDGE 0)
agens=# match (n:v{prop:1}) return n;
n
-------------------
v[3.1]{"prop": 1}
(1 row)
I want to following result after modifying vertex.
agens=# match (n:v{prop:2}) return n;
n
-------------------
v[3.1]{"prop": 2}
(1 row)
MATCH (a {prop:1})
SET a.prop=2;
--will do

in postgres, how to RI array elements?

with regular RI
create table t2(
c1 serial primary key,
c2 int references t1(c1) on delete cascade
);
create index t2_c2 on t1(c2);
what if c2 were an Array of integers?
is there any way to reference elements of the array
what is the best way to make sure the elements are indexed
create table t2(
c1 serial primary key,
c2 int[] -- ??
}
create index t2_c2 on t2( ?? );
(sure this has been asked and answered a thousand times, but for some reason out of my google-enable sphere)

Loop over data values in neo4j

I have a movies.csv file, which has a feature vector per line (E.g - id|Name|0|1|1|0|0|0|1 has 2 features for name and id, 7 features for genre classification)
I want a node m from class Movies to have a relationship [:HAS_GENRE] with nodes g from class Genres. For that, I need to loop over all the '|' separated features and only make a relationship if the value is 1.
IN essence, I want to have -
x = a //where a is the index of the first genre feature
while (x < lim) //lim is the last index of the feature vector
{
if line[x] is 1:
(m{id:toInt(line[0]})-[:HAS_GENRE]->(g{id=line[x]})
}
How do I do that?
try this
WITH ["Genre1","Genre2",...] as genres
LOAD CSV FROM "file:movies.pdv" using fieldterminator "|" AS row
MERGE (m:Movie {id:row[0]}) ON CREATE SET m.title = row[1]
FOREACH (idx in filter(range(0,size(genres)-1) WHERE row[2+idx]="1") ) |
MERGE (g:Genre {name:genres[idx]})
CREATE (m)-[:HAS_GENRE]->(g)
)
it loads each row of the file of as a collection
the first two elements are used to create a movie
then filter the potential indexes range(0,size(genres)-1) by the existence of a "1" in the input row,
the resulting list of indexes is then used to lookup the genre-name or id
and connect the movie with the genre

Updating multiple rows with respect to a change in one row

I am using PostgreSQL and let's say I have a tasks table to keep track of task items. Tasks table is as follows;
Id Name Index
7 name A 1
5 name B 2
6 name C 3
3 name D 4
Index column in tasks table stores the sort order of the tasks. Therefore I will output the tasks with respect to index in increasing order.
So When I change Task D(id = 3)' s index into 2 the new indexes should be as below;
Id Name Index
7 name A 1
5 name B 3
6 name C 4
3 name D 2
or when I change Task A(id = 7)' s index into 4 the new indexes should be as below;
Id Name Index
7 name A 4
5 name B 2
6 name C 3
3 name D 1
What I think is updating all row's index values one by one is pretty inefficient.
So what is the most efficient way to update all index values when I change one of the indexes in my Tasks table?
Edit :
First of all sorry for the confusion. What I am asking is not a simple exchanging two row indexes. If you look at the examples when I change Task D's index in to 2 more than one rows change. So when Task D is 2, Task B becomes 3 and Task C becomes 4.
For instance;
It is like when you drag Task D and drop below Task A so that it's index becomes 2 and B and C's index increases by 1.
SQL Fiddle
What you are doing is exchanging two row's indexes. So it is necessary to store the index value of the first updated one in a temp variable and setting it temporarily to a special value to avoid a unique index collision, that is, if the index is unique. If the index is not unique that step is unnecessary.
begin;
create temp table t as
select
(
select index
from tasks
where id = 3
) as index,
(
select id
from tasks
where index = 2
) as id
;
update tasks
set index = -1
where id = (select id from t)
;
update tasks
set index = 2
where id = 3
;
update tasks
set index = (select index from t)
where id = (select id from t)
;
drop table t;
commit;
The following assumes the index column (as well as id) is unique:
with swapped as (
select n1.id as id1,
n1.name as name1,
n1.index as index1,
n2.id as id2,
n2.name as name2,
n2.index as index2
from names n1
join names n2 on n2.index = 2 -- this is the value of the "new index"
where n1.id = 3 -- this is the id of the row where the index should be changed to the new value
)
update names as n
set index = case
when n.id = s.id1 then s.index2
when n.id = s.id2 then s.index1
end
from swapped s
where n.id in (s.id1, s.id2);
The CTE first creates a single row with the ids of the two rows to be swapped and then the update just compares the ids of the target table with those from the CTE, swapping the values.
SQLFiddle example: http://sqlfiddle.com/#!15/71dc2/1

Resources