Reputation: 13
I have the following collections, based on the example Arangodb doc here but have added a third collection called region
Users
{
"name" : {
"first" : "John",
"last" : "Doe"
},
"city" : "cities/2241300989",
"_id" : "users/2290649597",
"_rev" : "2290649597",
"_key" : "2290649597"
}
Cities
{
"population" : 1000,
"name" : "Metropolis",
"region" : "regions/2282300990",
"_id" : "cities/2241300989",
"_rev" : "2241300989",
"_key" : "2241300989"
}
Regions
{
"name" : "SomeRegion1",
"_id" : "regions/2282300990",
"_rev" : "2282300990",
"_key" : "2282300990"
}
I want to have a target result like this
[
{
"user" : {
"name" : {
"first" : "John",
"last" : "Doe"
},
"_id" : "users/2290649597",
"_rev" : "2290649597",
"_key" : "2290649597"
},
"city" : {
"population" : 1000,
"name" : "Metropolis",
"_id" : "cities/2241300989",
"_rev" : "2241300989",
"_key" : "2241300989",
"region" : {
"name" : "SomeRegion1",
"_id" : "regions/2282300990",
"_rev" : "2282300990",
"_key" : "2282300990"
}
}
}
]
The example in the Arangodb doc here only has queries for two collections
FOR u IN users
FOR c IN cities
FILTER u.city == c._id RETURN merge(u, {city: c})
# However I want to have more than two collections e.g.
FOR u IN users
FOR c IN cities
For r IN regions
FILTER u.city == c._id and c.region == r._id RETURN merge(????????)
How would you get the result with three collections joined as above? What happens if I want a forth nested one?
Upvotes: 1
Views: 930
Reputation: 2349
When you store a document _id
that references another collection, then you can leverage the DOCUMENT
AQL command.
So your AQL query becomes a bit simpler, like this:
FOR u IN users
LET city = DOCUMENT(u.city)
LET city_with_region = MERGE(city, { region: DOCUMENT(city.region})
RETURN MERGE(u, { city: city_with_region})
This query could be collapsed even more, but I left it like this so it's more self documenting.
What is cool about DOCUMENT
is you can return only a single attribute of a document, such as LET region_name = DOCUMENT(city.region).name
.
I've also found that in most cases it's more performant that doing a subquery to locate the document.
Upvotes: 1
Reputation: 2949
Probably something like this:
FOR u IN users
FOR c IN cities
For r IN regions
FILTER u.city == c._id AND c.region == r._id
RETURN { user: u, city: MERGE(c, {region: r } }
Is there a particular reason why you store ids instead of keys to refer to cities and regions? The _id
is just a virtual field that consists of the _key
prefixed by the collection name (plus a slash). So this would work just as well (I intentionally omit the internal _id and _rev fields):
Users
{
"name" : {
"first" : "John",
"last" : "Doe"
},
"city" : "2241300989",
"_key" : "2290649597"
}
Cities
{
"population" : 1000,
"name" : "Metropolis",
"region" : "2282300990",
"_key" : "2241300989"
}
Regions
{
"name" : "SomeRegion1",
"_key" : "2282300990"
}
FOR u IN users
FOR c IN cities
For r IN regions
FILTER u.city == c._key AND c.region == r._key
RETURN { user: u, city: MERGE(c, {region: r } }
Upvotes: 1