ashcrok
ashcrok

Reputation: 244

OrientDB query friend of friends with more information and filtering

Introduction:

Hi,

I have a question regarding how to create an OrientDB query. The query should get all the vertices of the friends of friends (this is equivalent to the second level relationship) + the bridge between the 2. After that, the query should filter the records after an edge property.

I am running OrientDB 1.7.4.

Schema example:

Let's take an example, taking the following schema:

-> User is a Vertex, with property id (int)

-> Knows is an Edge, with property type (string) (let's say this property has a few values: friend, family, etc.)

The relations I am looking for are like this:

User <--knows--> User <--knows--> User
(1)              (2)              (3)

I need all relations, doesn't matter what direction they have (even if the direction is important for other queries).

To get all Users (User3) of second degree, a query like this will suffice:

select expand( set(both().both()) ) from <rid> 

Questions:

Now, I have 2 main problems / questions I can't figure them out:

  1. If the query above return a list of records from the class User (User3), how can I get the record as User (User3) AND the User (or the property id) from the user in the middle of the relation (see above: User2)

  2. How can I filter the query to traverse (or select) only through edges that have a certain property. To be more specific I want the second query to find the Users that are from question 1 but that are friend of friends: User <--knows(method='friend')--> User <--knows(method='friend')--> User.

Upvotes: 0

Views: 648

Answers (2)

Sebastian
Sebastian

Reputation: 1263

You can do:

TREVERSE * FROM (SELECT FROM User WHERE id == 1)
WHILE (@class == 'User') OR (@class == 'Knows' AND method == 'friend')

This will give you all vertices and edges starting from vertex with id = 1.

If you want to stop at the 2nd level, then

TREVERSE * FROM (SELECT FROM User WHERE id == 1)
WHILE (@class == 'User') OR (@class == 'Knows' AND method == 'friend')
MAXDEPTH 2

If you only want to have vertices:

SELECT FROM (
    TREVERSE * FROM (SELECT FROM User WHERE id == 1)
    WHILE (@class == 'User') OR (@class == 'Knows' AND method == 'friend')
    MAXDEPTH 2
)
WHERE @class == 'User '

If you happen to need to know the path from the initial person to the last one, and all the possible paths from id = 1 up to the 2nd level.

SELECT $path FROM (
        TREVERSE * FROM (SELECT FROM User WHERE id == 1)
        WHILE (@class == 'User') OR (@class == 'Knows' AND method == 'friend')
        MAXDEPTH 2
    )

But if you have a fixed depth is better to do it with select, try this:

SELECT bothE('Knows')[method='friend'].bothV() FROM User WHERE id = 1

Upvotes: 0

ashcrok
ashcrok

Reputation: 244

As vitorenesduarte suggested, I found the answer. Yes I should look for edges, filter the edges, than take out the vertices from the edges, like following:

select expand( unionAll(inE('knows')[method='friend'].out, outE('knows')[method='friend'].in ) from <rid>

The problem with this query is that I think it could be optimized if OrientDB would have a function to take both way vertices from edges, something like this:

bothE('knows')[method='friend'].both

But the .both function doesn't exist (at least in the version I use, which is 1.7.4). If anyone knows something about this, please leave a comment.

Upvotes: 1

Related Questions