mirror of https://gitee.com/bigwinds/arangodb
172 lines
3.2 KiB
Plaintext
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"
|
|
]
|
|
}
|
|
]
|
|
```
|