2015-12-10 29 views
7

Ben Akl Graph Operation ve Graphs okuyordum ve SQL-Traverse kullanımı durum için hiçbir somut örneği ve performans açıklamasını bulduk., O (n) 'de yapılabilir komşu (ler) den, filtreler, sorgulama olacaktır?

Örn:

Bir koleksiyonunuz varsa Kullanıcılar

Şirket koleksiyonuna bir şirket ilişkisi, Koleksiyon Şirket toplama Location ilişkisi konumu sahiptir;

Koleksiyon Yer ya bir şehir, ülke veya bölge ve aralarındaki bağa kenti, ülkeyi, kendisine bölgeyi sahiptir.

Şimdi, Almanya veya AB'de şirketlere ait tüm kullanıcıları sorgulamak istiyorum.

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

veya Location.name dizine varsayılarak

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

, yukarıdaki iki sorgu olabilir O (n), N doküman sayısı olmak üzere yürütülen Bulunduğu yer (O (1) Grafik için traversal, O (n) İndeks taraması için)? Tabii

, sadece bu şehirler ve ülkeler içinde ... başka yerlerde, muhtemelen değişmeyecek aksine AB'de, ancak olarak, RegionName veya şirket doğrudan countryName kurtarabilecek ne olur ... ne demek istediğimi

cevap

4

Bu using the ArangoDB 2.8 Traversals açıklamak için gidiyorum (ben sürekli güncelleştirme gerektiren diğer kullanım durumları varsa, ne şaka) biliyorum.

Biz arangosh kullanarak Shema maç için bu koleksiyonları oluşturun: AQL olarak

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

etrafında bu sorgu başka bir yol yazardı. Biz endeksli özniteliği name üzerinde sabit zaman FILTER ile başlar ve orada bizim traversals başlar. Gerekçesi biz ülke "Almanya" için filtre:

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 

Şimdi bizim de filtrelenmiş başlangıç ​​düğümü olduğuna göre ters yönde bir grafik geçişi yapmak.

    :

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

    bu konuda bazı kelimeler performans sorgular: Biz Employees tam 3 adım ötede başından Vertex gelen, ve biz yola ilgilenmiyoruz olduğunu bildiğimiz için, sadece 3 katmanı döndürmek

  • Biz Almanya bir karma indeks kullanılarak yerini sürekli zaman ->o (1) m birçok yollara istediğiniz dayanarak
  • m burada t, Almanya numaralı çalışan sayısı; Her biri sabit zamanda geçebilir. ->O (m) bu adımda.
  • İade sabit zamanda sonuç ->O (1)

    Tüm ihtiyacımız kombine Ey biz m çalışanların daha az n (sayı olmasını bekliyoruz (m)) SQL-Traversal'inizde kullanıldığı gibi.

+0

Ah, anladım, bu yüzden ben takip Almanya'da bakmak" için sormalısınız yerine "Bana şehir Ülkesi Almanya ise kullanıcıların bir listesini almak" demek, benim zihniyet değiştirmek gerekir Kullanıcılara ulaşana kadar yolları ve bana bu listeyi al. Ya da 1'den fazla koşul varsa (burada ayarlanan eski zihin için üzgünüm) Users from users.company.location.city.country.name = "Germany" ve Users.department.parent.parent = "Ürün geliştirme"; "Bölüm" ile , hiyerarşik olabilir (tıpkı konum gibi), ör. "Backend" -> "Web geliştirme" -> "Yazılım geliştirme" -> "Ürün geliştirme"? – TruongSinh

+0

Yukarıda açıklanan senaryo için uygun "grafik kesişimi", ve o, Almanya'da çalışanlar ve n "Ürün geliştirme" departmanındaki çalışanların sayısı ise m'nin sayı olduğu O (m + n) midir? Ve 'GRAPH_COMMON_NEIGHBORS' doğru işlevi nedir? – TruongSinh

+0

[Trailer kısmına [FILTER ifadeleri] ekleyebilirsiniz (https://docs.arangodb.com/devel/Aql/GraphTraversals.html#filter-examples) ve bu nedenle path.vertices [3] gibi bir şeye filtre uygulamak isteyebilirsiniz. ] .department == "ürün geliştirme" - veya başka bir koleksiyondan geliyorsa, önce bu bölümü bir LET departmanı ile alabilirsiniz. (FOR d IN bölümleri FILTER name = "Product Development" RETURN d) ' – dothebart