admin 管理员组

文章数量: 887016

ArangoDB高级查询(二)

连接查询

在这之前我们插入如下的数据

{

"name": "Ned",

"surname": "Stark",

"alive": false,

"age": 41,

"traits": ["A","H","C","N","P"]

}

"traits": ["A","H","C","N","P"]是一个没有明显含义的字母表,它们是另一个集合的文档关键字,我们可以使用这些关键字来将这些字母解析为诸如“strong”之类的标签。为实际特征使用另一个集合的好处是,我们可以在以后轻松查询所有现有特征,并将标签以多种语言存储在中心位置。如果我们直接嵌入特征...

{

"name": "Ned",

"surname": "Stark",

"alive": false,

"age": 41,

"traits": [

{

"de": "stark",

"en": "strong"

},

{

"de": "einflussreich",

"en": "powerful"

},

{

"de": "loyal",

"en": "loyal"

},

{

"de": "rational",

"en": "rational"

},

{

"de": "mutig",

"en": "brave"

}

]

}

......保持特征变得非常困难。如果您要重命名或翻译其中的一个,则需要查找具有相同特征的所有其他字符文档,并在其中执行更改。如果我们只是在另一个集合中引用一个特征,它就像更新单个文档一样简单。

数据模型比较

导入特征

创建一个文档集合Traits

LET data =[

{ "_key": "A", "en": "strong", "de": "stark" },

{ "_key": "B", "en": "polite", "de": "freundlich" },

{ "_key": "C", "en": "loyal", "de": "loyal" },

{ "_key": "D", "en": "beautiful", "de": "schön" },

{ "_key": "E", "en": "sneaky", "de": "hinterlistig" },

{ "_key": "F", "en": "experienced", "de": "erfahren" },

{ "_key": "G", "en": "corrupt", "de": "korrupt" },

{ "_key": "H", "en": "powerful", "de": "einflussreich" },

{ "_key": "I", "en": "naive", "de": "naiv" },

{ "_key": "J", "en": "unmarried", "de": "unverheiratet" },

{ "_key": "K", "en": "skillful", "de": "geschickt" },

{ "_key": "L", "en": "young", "de": "jung" },

{ "_key": "M", "en": "smart", "de": "klug" },

{ "_key": "N", "en": "rational", "de": "rational" },

{ "_key": "O", "en": "ruthless", "de": "skrupellos" },

{ "_key": "P", "en": "brave", "de": "mutig" },

{ "_key": "Q", "en": "mighty", "de": "mächtig" },

{ "_key": "R", "en": "weak", "de": "schwach" }

]

只返回每个字符的traits属性:

FOR c IN Characters

RETURN c.traits

[

{ "traits": ["A","H","C","N","P"] },

{ "traits": ["D","H","C"] },

...

]

我们可以使用traits数组和DOCUMENT()函数一起使用元素作为文档键,并在Traits集合中查找它们:

FOR c IN Characters

RETURN DOCUMENT("Traits", c.traits)

[

[

{

"_key": "A",

"_id": "Traits/A",

"_rev": "_V5oRUS2---",

"en": "strong",

"de": "stark"

},

{

"_key": "H",

"_id": "Traits/H",

"_rev": "_V5oRUS6--E",

"en": "powerful",

"de": "einflussreich"

},

{

"_key": "C",

"_id": "Traits/C",

"_rev": "_V5oRUS6--_",

"en": "loyal",

"de": "loyal"

},

{

"_key": "N",

"_id": "Traits/N",

"_rev": "_V5oRUT---D",

"en": "rational",

"de": "rational"

},

{

"_key": "P",

"_id": "Traits/P",

"_rev": "_V5oRUTC---",

"en": "brave",

"de": "mutig"

}

],

[

{

"_key": "D",

"_id": "Traits/D",

"_rev": "_V5oRUS6--A",

"en": "beautiful",

"de": "schön"

},

{

"_key": "H",

"_id": "Traits/H",

"_rev": "_V5oRUS6--E",

"en": "powerful",

"de": "einflussreich"

},

{

"_key": "C",

"_id": "Traits/C",

"_rev": "_V5oRUS6--_",

"en": "loyal",

"de": "loyal"

}

],

...

]

上面返回的信息太冗余,我们只返回英文标签:

FOR c IN Characters

RETURN DOCUMENT("Traits", c.traits)[*].en

[

[

"strong",

"powerful",

"loyal",

"rational",

"brave"

],

[

"beautiful",

"powerful",

"loyal"

],

...

]

合并Characters和特征

我们traits解析为有意义的特征!我们需要合并字符文档和特质文档中的数据:

FOR c IN Characters

RETURN MERGE(c, { traits: DOCUMENT("Traits", c.traits)[*].en } )

[

{

"_id": "Characters/2861650",

"_key": "2861650",

"_rev": "_V1bzsXa---",

"age": 41,

"alive": false,

"name": "Ned",

"surname": "Stark",

"traits": [

"strong",

"powerful",

"loyal",

"rational",

"brave"

]

},

{

"_id": "Characters/2861653",

"_key": "2861653",

"_rev": "_V1bzsXa--B",

"age": 40,

"alive": false,

"name": "Catelyn",

"surname": "Stark",

"traits": [

"beautiful",

"powerful",

"loyal"

]

},

...

]

MERGE()函数将对象合并在一起。因为我们使用与原始字符属性{ traits: ... }具有相同属性名称特征的对象 ,所以后者被合并覆盖。

查询总数

for l in loginTb

filter l.cust_no=='123456'

COLLECT WITH COUNT INTO length

return length

#返回指定数据

FORu INusers

RETURN{name:u.name,friends:u.friends[*].name}

FORu INusers

LETfriends=(

FORf INfriends

FILTER u.id==f.userId

RETURNf

)

LETmemberships=(

FORm IN memberships

FILTER u.id==m.userId

RETURNm

)

RETURN{

"user" : u,

"friends" : friends,

"numFriends" : LENGTH(friends),

"memberShips" : memberships

}

地理空间查询

地点数据

让我们将一些拍摄位置插入到新集合Locations中,然后在AQL查询下运行:

创建地点集合

LET places = [

{ "name": "Dragonstone", "coordinate": [ 55.167801, -6.815096 ] },

{ "name": "King's Landing", "coordinate": [ 42.639752, 18.110189 ] },

{ "name": "The Red Keep", "coordinate": [ 35.896447, 14.446442 ] },

{ "name": "Yunkai", "coordinate": [ 31.046642, -7.129532 ] },

{ "name": "Astapor", "coordinate": [ 31.50974, -9.774249 ] },

{ "name": "Winterfell", "coordinate": [ 54.368321, -5.581312 ] },

{ "name": "Vaes Dothrak", "coordinate": [ 54.16776, -6.096125 ] },

{ "name": "Beyond the wall", "coordinate": [ 64.265473, -21.094093 ] }

]

FOR place IN places

INSERT place INTO Locations

查找附近的位置

查询距指定坐标位置最近的三个地址,near()函数默认查询附近100个位置。

FOR loc IN NEAR(Locations, 53.35, -6.26, 3)

RETURN {

name: loc.name,

latitude: loc.coordinate[0],

longitude: loc.coordinate[1]

}

[

{

"name": "Vaes Dothrak",

"latitude": 54.16776,

"longitude": -6.096125

},

{

"name": "Winterfell",

"latitude": 54.368321,

"longitude": -5.581312

},

{

"name": "Dragonstone",

"latitude": 55.167801,

"longitude": -6.815096

}

]

查找半径内的位置

WITHIN(),从参考点搜索给定半径内的位置。第四个参数,它指定半径而不是限制。半径的单位是米。该示例使用200,000米(200公里)的半径:

FOR loc IN WITHIN(Locations, 53.35, -6.26, 200 * 1000)

RETURN {

name: loc.name,

latitude: loc.coordinate[0],

longitude: loc.coordinate[1]

}

[

{

"name": "Vaes Dothrak",

"latitude": 54.16776,

"longitude": -6.096125

},

{

"name": "Winterfell",

"latitude": 54.368321,

"longitude": -5.581312

}

]

返回距离

NEAR()和WITHIN()可以通过添加一个可选的第五个参数返回到参考点的距离。它必须是一个字符串,它将用作距离为米的附加属性的属性名称:

FOR loc IN NEAR(Locations, 53.35, -6.26, 3, "distance")

RETURN {

name: loc.name,

latitude: loc.coordinate[0],

longitude: loc.coordinate[1],

distance: loc.distance / 1000

}

[

{

"name": "Vaes Dothrak",

"latitude": 54.16776,

"longitude": -6.096125,

"distance": 91.56658640314431

},

{

"name": "Winterfell",

"latitude": 54.368321,

"longitude": -5.581312,

"distance": 121.66399816395028

},

{

"name": "Dragonstone",

"latitude": 55.167801,

"longitude": -6.815096,

"distance": 205.31879386198324

}

]

示例查询中的值除以1000,将单位转换为公里。

本文标签: ArangoDB高级查询(二)