Cartesian空間探索
Cartesian空間探索クエリーの作成。
Cartesian空間クエリーは、Cartesian(グラフ化可能)情報を発見するために使用します。すべてのCartesianデータ型(ポイント、ラインストリング、およびポリゴン)に対し、指定した値を単純なクエリーで検索できます。より複雑な探索クエリーでは、指定したポイントの半径内または指定した空間ポリゴン内のポイントまたはラインストリングを検出します。
DSE Searchインデックスを作成すると応答時間のレイテンシーを短縮できますが、これは必須ではありません。point
およびlinestring
プロパティの検索インデックスを使用するためのスキーマは、Cartesianスキーマで作成します。
スキーマとデータ
// SCHEMA
// POINT
schema.propertyKey('name').Text().create()
schema.propertyKey('point').Point().withBounds(-3, -3, 3, 3).create()
schema.vertexLabel('location').properties('name','point').create()
// LINESTRING
schema.propertyKey('line').Linestring().withBounds(-3, -3, 3, 3).create()
schema.vertexLabel('lineLocation').properties('name','line').create()
// POLYGON
schema.propertyKey('polygon').Polygon().withBounds(-3, -3, 3, 3).create()
schema.vertexLabel('polyLocation').properties('name','polygon').create()
// MATERIALIZED VIEW INDEXES
schema.vertexLabel('location').index('byname').materialized().by('name').add()
schema.vertexLabel('lineLocation').index('byname').materialized().by('name').add()
schema.vertexLabel('polyLocation').index('byname').materialized().by('name').add()
//SEARCH INDEX - ONLY WORKS FOR POINT AND LINESTRING
schema.vertexLabel('location').index('search').search().by('point').add()
schema.vertexLabel('lineLocation').index('search').search().by('line').add()
/// Create a point
graph.addVertex(label,'location','name','p0','point',Geo.point(0.5,0.5))
graph.addVertex(label,'location','name','p1','point',Geo.point(1,1))
graph.addVertex(label,'location','name','p2','point',Geo.point(-1,1))
graph.addVertex(label,'location','name','p3','point',Geo.point(-2,-2))
graph.addVertex(label,'location','name','p4','point',Geo.point(2,2))
// Create a linestring
graph.addVertex(label, 'lineLocation', 'name', 'l1', 'line', "LINESTRING(0 0, 1 1)")
graph.addVertex(label, 'lineLocation', 'name', 'l2', 'line', "LINESTRING(0 0, -1 1)")
graph.addVertex(label, 'lineLocation', 'name', 'l3', 'line', "LINESTRING(0 0, -2 -2)")
graph.addVertex(label, 'lineLocation', 'name', 'l4', 'line', "LINESTRING(0 0, 2 -2)")
// Create a polygon
graph.addVertex(label, 'polyLocation','name', 'g1', 'polygon',Geo.polygon(0,0,1,1,0,1,0,0))
graph.addVertex(label, 'polyLocation','name', 'g2', 'polygon',Geo.polygon(0,0,0,1,-1,1,0,0))
graph.addVertex(label, 'polyLocation','name', 'g3', 'polygon',Geo.polygon(0,0,-2,0,-2,-2,0,0))
graph.addVertex(label, 'polyLocation','name', 'g4', 'polygon',Geo.polygon(0,0,2,0,2,-2,0,0))
指定された情報に一致する、格納されているCartesian空間データの検索
g.V().
has('location','point', Geo.point(0.5, 0.5)).
valueMap()
結果:{name=[p0], point=[POINT (0.5 0.5)]}
g.V().
has('lineLocation','line',Geo.lineString(0, 0, 1, 1)).
valueMap()
結果:{line=[LINESTRING (0 0, 1 1)], name=[l1]}
g.V().
has('polyLocation', 'polygon',Geo.polygon(0,0,1,1,0,1,0,0)).
valueMap()
結果:{polygon=[POLYGON ((0 0, 1 1, 0 1, 0 0))], name=[g1]}
指定されたポイントを中心とした、指定された半径以内の、格納されているCartesian空間ポイントまたはラインストリングの検索
これらのクエリー、および指定されたCartesian空間ポリゴンを使用するクエリーでは、ポイントおよび半径を指定するGeo.inside()
メソッドを使用します。
g.V().
has('location', 'point', Geo.inside(Geo.point(0, 0), 1)).
values('name')
リスト:==>p0
クエリーの中心を(0, 0)にして1ユニット内を検索すると、データセットから1ポイントp0が返されます。 g.V().has('lineLocation', 'line', Geo.inside(Geo.point(0.0, 0.0), 1.415)).valueMap()
リスト:==>{line=[LINESTRING (0 0, 1 1)], name=[l1]}
==>{line=[LINESTRING (0 0, -1 1)], name=[l2]}
クエリーのセンターを(0, 0)にして1.415ユニット内を検索すると、格納されている次の2つのラインストリングが返されます:l1およびl2。指定されたCartesian空間ポリゴン内の、格納されているCartesian空間ポイントまたはラインストリングの検索
これらのクエリーでポリゴンを使用して、ポリゴンのあるポイントを検索できます。
g.V().
has('location', 'point', Geo.inside(Geo.polygon(0, 0, 1, 0, 1, 1, 0, 1, 0, 0))).
values('name')
リスト:==>p0
g.V().
has('lineLocation', 'line', Geo.inside(Geo.polygon(0, 0, 1, 0, 1, 1, 0, 1, 0, 0))).
values('name')
リスト:==>l1
スキーマとデータ
///SCHEMA
// PROPERTY KEYS
// Check for previous creation of property key with ifNotExists()
schema.propertyKey('name').Text().ifNotExists().create()
schema.propertyKey('address').Text().ifNotExists().create()
schema.propertyKey('location').Point().withBounds(-100,-100,100,100).ifNotExists().create()
// VERTEX LABELS
schema.vertexLabel('person').properties('name').ifNotExists().create()
schema.vertexLabel('home').properties('address','location').ifNotExists().create()
schema.vertexLabel('store').properties('name','location').ifNotExists().create()
schema.vertexLabel('ingredient').properties('name').ifNotExists().create()
// EEDGE LABELS
schema.edgeLabel('livesIn').connection('person','home').ifNotExists().create()
schema.edgeLabel('isStockedWith').connection('store','ingredient').multiple().ifNotExists().create()
// SEARCH INDEXES
schema.vertexLabel('person').index('search').search().by('name').asString().ifNotExists().add()
schema.vertexLabel('home').index('search').search().by('name').by('location').add();
schema.vertexLabel('store').index('search').search().by('name').by('location').add();
schema.vertexLabel('ingredient').index('search').search().by('name').add();
//VERTICES
// PERSON VERTICES
pam = graph.addVertex(label, 'person', 'name','Pam')
les = graph.addVertex(label, 'person', 'name','Les')
paul = graph.addVertex(label, 'person', 'name','Paul')
victoria = graph.addVertex(label, 'person', 'name','Victoria')
terri = graph.addVertex(label, 'person', 'name','Terri')
// HOME VERTICES
home1 = graph.addVertex(label, 'home', 'address', '555 4th St', 'location', Geo.point(7,2));
home2 = graph.addVertex(label, 'home', 'address', '1700 Coyote Rd', 'location', Geo.point(-2,1));
home3 = graph.addVertex(label, 'home', 'address', '99 Mountain Pass Hwy', 'location', Geo.point(0,0));
// STORE VERTICES
store1 = graph.addVertex(label, 'store', 'name', 'ZippyMart', 'location', Geo.point(1,5));
store2 = graph.addVertex(label, 'store', 'name', 'Quik Station', 'location', Geo.point(7,-1));
store3 = graph.addVertex(label, 'store', 'name', 'Mamma's Grocery', 'location', Geo.point(-3,-3));
// INGREDIENT VERTICES
celery = graph.addVertex(label, 'ingredient','name', 'celery');
milk = graph.addVertex(label, 'ingredient','name', 'milk');
bokChoy = graph.addVertex(label, 'ingredient','name', 'bok choy');
steak = graph.addVertex(label, 'ingredient','name', 'steak');
carrots = graph.addVertex(label, 'ingredient','name', 'carrots');
porkChops = graph.addVertex(label, 'ingredient','name', 'pork chops');
// PERSON - HOME EDGES
pam.addEdge('livesIn', home1);
les.addEdge('livesIn', home1);
paul.addEdge('livesIn',home3);
victoria.addEdge('livesIn',home3);
terri.addEdge('livesIn',home2);
// STORE - INGREDIENT EDGES
store1.addEdge('isStockedWith', milk);
store1.addEdge('isStockedWith', bokChoy);
store1.addEdge('isStockedWith', steak);
store2.addEdge('isStockedWith', steak);
store2.addEdge('isStockedWith', carrots);
store2.addEdge('isStockedWith', porkChops);
store3.addEdge('isStockedWith', milk);
store3.addEdge('isStockedWith', carrots);
store3.addEdge('isStockedWith', celery);
セロリの検索
あなたは数学の教師で、生徒のために単純なCartesian問題を作成しようとしています。生徒は丸太の上の蟻と呼ばれる、セロリ、クリーム・チーズ、レーズンで作るおやつが大好きです。このため、生徒の家から一番近い、セロリを販売している店を検索するためのお手伝いをすることにしました。
g.V().has('store', 'location', Geo.inside(Geo.point(0,0),10)).
values('name')
結果:==>ZippyMart
==>Quik Station
==>Mamma's Grocery
この演習ではデカルト座標点間で計算されたCartesian座標と距離を使用していますが、類似の演習では地理空間データを使用できます。g.V().has('store', 'location', Geo.inside(Geo.point(0,0),10)).as('Store').
out().has('name','celery').as('Ingred').
select('Store', 'Ingred').
by('name').
by('name')
検索結果:==>{Store=ZippyMart, Ingred=celery}
==>{Store=Quik Station, Ingred=celery}
==>{Store=Mamma's Grocery, Ingred=celery}
このクエリーでは、「単純な探索」で説明されている、as()
、out()
、select()
などの一般的なメソッドを使用して検索結果を絞ります。// List store name, location, and ingredient in order by distance from the store
g.V().has('store', 'location', Geo.inside(Geo.point(0,0),25)).as('Store').
order().by{it.value('location').getOgcGeometry().distance(Geo.point(0,0).getOgcGeometry())}.
as('Location').
out().has('name','celery').as('Ingred').
select('Store', 'Location','Ingred').
by('name').
by('location').
by('name')
==>{Store=Mamma's Grocery, Location=POINT (-3 -3), Ingred=celery}
==>{Store=ZippyMart, Location=POINT (1 5), Ingred=celery}
==>{Store=Quik Station, Location=POINT (7 -1), Ingred=celery}
このクエリーは、order()
メソッドを追加して結果をソートします。これについては「単純な探索」でも説明されています。このクエリーは、クエリーの実行を成功させるためにインポートしなければならない次のメソッドも使用する必要があります。これらはgetOgcGeometry()
とdistance()
です。ライブラリのインポートは、以下を使用して元のスクリプトで実行できます。import com.esri.core.geometry.ogc.OGCGeometry;
これでこの問題に取り組んでいる生徒には、お気に入りのおやつを作るために必要なセロリを買うために行く店がMamma's Groceryであることがわかりました。