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, a 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"
]
}
]
```