1
0
Fork 0
arangodb/Documentation/Books/Users/AqlExamples/Join.mdpp

172 lines
3.2 KiB
Plaintext

!CHAPTER Joins
So far we have only dealt with one collection (*users*) at a time. We also have a
collection *relations* that stores relationships between users. We will now use
this extra collection to create a result from two collections.
First of all, we'll query a few users together with their friends' ids. For that,
we'll use all *relations* that have a value of *friend* in their *type* attribute.
Relationships are established by using the *from* and *to* attributes in the
*relations* collection, which point to the *id* values in the *users* collection.
!SUBSECTION Join tuples
We'll start with a SQL-ish result set and return each tuple (user name, friend id)
separately. The AQL query to generate such result is:
```js
FOR u IN users
FILTER u.active == true
LIMIT 0, 4
FOR f IN relations
FILTER f.type == "friend" && f.from == u.id
RETURN {
"user" : u.name,
"friendId" : f.to
}
[
{
"user" : "Abigail",
"friendId" : 108
},
{
"user" : "Abigail",
"friendId" : 102
},
{
"user" : "Abigail",
"friendId" : 106
},
{
"user" : "Fred",
"friendId" : 209
},
{
"user" : "Mary",
"friendId" : 207
},
{
"user" : "Mary",
"friendId" : 104
},
{
"user" : "Mariah",
"friendId" : 203
},
{
"user" : "Mariah",
"friendId" : 205
}
]
```
!SUBSECTION Horizontal lists
Note that in the above result, an user might be returned multiple times. This is the
SQL way of returning data. If this is not desired, the friends' ids of each user
can be returned in a horizontal list. This will return each user at most once.
The AQL query for doing so is:
```js
FOR u IN users
FILTER u.active == true LIMIT 0, 4
RETURN {
"user" : u.name,
"friendIds" : (
FOR f IN relations
FILTER f.from == u.id && f.type == "friend"
RETURN f.to
)
}
[
{
"user" : "Abigail",
"friendIds" : [
108,
102,
106
]
},
{
"user" : "Fred",
"friendIds" : [
209
]
},
{
"user" : "Mary",
"friendIds" : [
207,
104
]
},
{
"user" : "Mariah",
"friendIds" : [
203,
205
]
}
]
```
In this query we are still iterating over the users in the *users* collection
and for each matching user we are executing a sub-query to create the matching
list of related users.
!SUBSECTION Self joins
To not only return friend ids but also the names of friends, we could "join" the
*users* collection once more (something like a "self join"):
```js
FOR u IN users
FILTER u.active == true
LIMIT 0, 4
RETURN {
"user" : u.name,
"friendIds" : (
FOR f IN relations
FILTER f.from == u.id && f.type == "friend"
FOR u2 IN users
FILTER f.to == u2.id
RETURN u2.name
)
}
[
{
"user" : "Abigail",
"friendIds" : [
"Jim",
"Jacob",
"Daniel"
]
},
{
"user" : "Fred",
"friendIds" : [
"Mariah"
]
},
{
"user" : "Mary",
"friendIds" : [
"Isabella",
"Michael"
]
},
{
"user" : "Mariah",
"friendIds" : [
"Madison",
"Eva"
]
}
]
```