在ArangoDB中,使用过滤器查询邻居是否在O(n)中完成?

我一直在阅读Aql图形操作和图形,并没有找到SQL-Traverse用例的具体示例和性能说明。

例如:

如果我有一个收集用户,它与收集公司有一个公司关系

收款公司与收款地点有关联的地点;

收藏位置既可以是城市,国家或地区,也可以与城市,国家,地区相关联。

现在,我想查询属于德国或欧盟公司的所有用户。

SELECT from Users where Users.company.location.city.country.name="Germany";
SELECT from Users where Users.company.location.city.parent.name="Germany";

要么

SELECT from Users where Users.company.location.city.country.region.name="europe";
SELECT from Users where Users.company.location.city.parent.parent.name="europe";

假设Location.name是索引的,我可以使用O(n)执行上述两个查询,其中n是Location中的文档数(O(1)用于图遍历,O(n)用于索引扫描)?

当然,我可以直接在公司里保存regionName或countryName,因为这些城市和国家在欧盟,不像其他地方,不会在其他地方改变,但如果......你知道我的意思(开玩笑,如果我有其他需要不断更新的用例,该怎么办)


我将使用ArangoDB 2.8遍历来解释这一点。

我们使用arangosh创建这些集合以匹配您的shema:

db._create("countries")
db.countries.save({_key:"Germany", name: "Germany"})
db.countries.save({_key:"France", name: "France"})
db.countries.ensureHashIndex("name")

db._create("cities")
db.cities.save({_key: "Munich"})
db.cities.save({_key: "Toulouse")

db._create("company")
db.company.save({_key: "Siemens"})
db.company.save({_key: "Airbus"})

db._create("employees")
db.employees.save({lname: "Kraxlhuber", cname: "Xaver", _key: "user1"})
db.employees.save({lname: "Heilmann",  cname: "Vroni",  _key: "user2"})
db.employees.save({lname: "Leroy",  cname: "Marcel",  _key: "user3"})

db._createEdgeCollection("CityInCountry")
db._createEdgeCollection("CompanyIsInCity")
db._createEdgeCollection("WorksAtCompany")


db.CityInCountry.save("cities/Munich", "countries/Germany", {label: "beautiful South near the mountains"})
db.CityInCountry.save("cities/Toulouse", "countries/France", {label: "crowded city at the mediteranian Sea"})

db.CompanyIsInCity.save("company/Siemens", "cities/Munich", {label: "darfs ebbes gscheits sein? Oder..."})
db.CompanyIsInCity.save("company/Airbus", "cities/Toulouse", {label: "Big planes Ltd."})


db.WorksAtCompany.save("employees/user1", "company/Siemens", {employeeOfMonth: true})
db.WorksAtCompany.save("employees/user2", "company/Siemens", {veryDiligent: true})
db.WorksAtCompany.save("employees/user3", "company/Eurocopter", {veryDiligent: true})

在AQL中,我们会用另一种方式写这个查询。 我们从索引属性name上的常量时间FILTER开始,并从那里开始遍历。 因此,我们筛选国家“德国”:

db._explain("FOR country IN countries FILTER country.name == 'Germany' RETURN country ")
Query string:
 FOR country IN countries FILTER country.name == 'Germany' RETURN country 

Execution plan:
 Id   NodeType        Est.   Comment
  1   SingletonNode      1   * ROOT
  6   IndexNode          1     - FOR country IN countries   /* hash index scan */
  5   ReturnNode         1       - RETURN country

Indexes used:
 By   Type   Collection   Unique   Sparse   Selectivity   Fields       Ranges
  6   hash   countries    false    false        66.67 %   [ `name` ]   country.`name` == "Germany"

Optimization rules applied:
 Id   RuleName
  1   use-indexes
  2   remove-filter-covered-by-index

现在我们有了我们良好过滤的起始节点,我们在相反的方向进行图遍历。 既然我们知道Employees距离Vertex开始只有3步,并且我们对路径不感兴趣,我们只返回第3层:

db._query("FOR country IN countries FILTER country.name == 'Germany' FOR v IN 3 INBOUND country CityInCountry, CompanyIsInCity, WorksAtCompany  RETURN v")

[ 
  { 
    "cname" : "Xaver", 
    "lname" : "Kraxlhuber", 
    "_id" : "employees/user1", 
    "_rev" : "1286703864570", 
    "_key" : "user1" 
  }, 
  { 
    "cname" : "Vroni", 
    "lname" : "Heilmann", 
    "_id" : "employees/user2", 
    "_rev" : "1286729095930", 
    "_key" : "user2" 
  } 
]

关于这个查询性能的一些话:

  • 我们使用哈希指数定位德国是恒定时间 - > O(1)
  • 基于此,我们想要遍历许多路径,其中m是德国雇员的数量; 它们中的每一个都可以在一段时间内遍历。 - > O(m)在这一步。
  • 在常量时间内返回结果 - > O(1)

    所有组合,我们需要O(m) ,其中我们希望m小于n(员工数量),正如在SQL遍历中所使用的那样。

  • 链接地址: http://www.djcxy.com/p/89195.html

    上一篇: In ArangoDB, will querying, with filters, from the neighbor(s) be done in O(n)?

    下一篇: Merging two strings that overlap