Wyjaśnię to using the ArangoDB 2.8 Traversals.
Tworzymy tych zbiorów, aby dopasować swój Szema użyciu arangosh:
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})
W AQL będziemy pisać tego zapytania na odwrót. Zaczynamy od stałego czasu FILTER
na indeksowanym atrybucie name
i od tego momentu uruchamiamy nasze przewijanie. Nich filtrujemy dla kraju „Niemcy”:
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
Teraz, gdy mamy dobrze filtrowaną węzeł początkowy, robimy przechodzenie wykres w odwrotnym kierunku.Ponieważ wiemy, że Employees
są dokładnie 3 kroków od początku Vertex, a my nie jesteśmy zainteresowani w ścieżce, tylko wrócić 3rd warstwy:
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"
}
]
Kilka słów o to pyta wydajność:
Och, rozumiem, więc powinienem zmienić zdanie, zamiast mówić: "wyślij mi listę użytkowników, których miastem jest Niemcy", powinienem zapytać o "spójrz na Niemcy, podążaj za ścieżki, dopóki nie dotrzesz do użytkowników i nie zdobędziesz tej listy ". Następnie, jeśli mam więcej niż jeden warunek (przepraszam za stary zestaw umysłu) SELECT od użytkowników, gdzie Users.company.location.city.country.name = "Niemcy" i Users.department.parent.parent = "Opracowywanie produktu"; z "działem" może być hierarchiczny (podobnie jak lokalizacja), np. "Backend" -> "Web development" -> "Tworzenie oprogramowania" -> "Rozwój produktu"? – TruongSinh
Czy "skrzyżowanie wykresów" jest odpowiednie dla opisanego powyżej scenariusza i czy jest to O (m + n), gdzie m jest liczbą, jeśli pracownicy w Niemczech i n to liczba pracowników w dziale "Rozwój produktu"? A czy "GRAPH_COMMON_NEIGHBORS" jest właściwą funkcją? – TruongSinh
Możesz dodać [instrukcje FILTER do części traversal] (https://docs.arangodb.com/devel/Aql/GraphTraversals.html#filter-examples) i prawdopodobnie zechcesz filtrować coś podobnego do path.vertices [3 ] .department == "rozwój produktu" - lub jeśli pochodzi z innej kolekcji, możesz najpierw uzyskać ten dział z 'działem LET = (dla działów d IN FILTER name =" Rozwój produktu "POWRÓT d)' – dothebart