Arangodb AQL Joining, merging, embedding 嵌套三个集合或更多

Arangodb AQL Joining, merging, embedding nested three collections or more

我有以下集合,基于示例 Arangodb 文档 here 但添加了第三个集合,称为 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" 
} 

我想要这样的目标结果

[ 
  { 
    "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" 
      }
    } 
  } 
]

Arangodb 文档中的示例here 仅查询了两个集合

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(????????)

如上连接三个集合,您将如何得到结果?如果我想要第四个嵌套的会怎样?

大概是这样的:

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 } }

您存储 ID 而不是键来引用城市和地区是否有特殊原因? _id 只是一个虚拟字段,由 _key 组成,前缀为集合名称(加上斜杠)。所以这也可以工作(我有意省略内部 _id 和 _rev 字段):

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 } }

当您存储引用另一个集合的文档 _id 时,您可以利用 DOCUMENT AQL 命令。

所以你的 AQL 查询变得更简单了,像这样:

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})

这个查询可以折叠得更多,但我把它留成这样,这样它更能自我记录。

DOCUMENT 的妙处在于您可以 return 文档的单个属性,例如 LET region_name = DOCUMENT(city.region).name.

我还发现,在大多数情况下,执行子查询来定位文档的性能更高。