ArangoDB 自定义排序顺序
ArangoDB custom sort order
我想按特定顺序按字段排序,比方说 2,4,1,5,3。
在 MySQL 中我可以使用 ORDER BY FIELD(id,2,4,1,5,3)
。
ArangoDB 有什么等价物吗?
遗憾的是,目前没有直接对应的方法。
但是,有一些方法可以自己完成。
1) 通过构建AQL查询:
该查询将 运行 通过您的排序值数组并查询数据库以获取每个定义的值。然后将这些结果中的每一个添加到最终输出数组中。
请注意,这确实会降低性能,因为每个值都有一个查询。如果你只定义几个,我想这是可以容忍的,但如果你必须定义例如几十或几百,它将导致 n+1 查询(其中 n 是自定义排序值的数量)。
“+1”是最后一个查询,它应该获取所有其他值的结果,这些值未在您的自定义排序数组中定义,并将它们附加到您的输出数组。
这看起来像下面的代码片段,您可以将其复制到 AQL 编辑器中并 运行 它。
片段注释:
- 我首先创建一个数组,它代表我们的集合
会查询。
- 然后我正在设置定义的排序值。
- 之后,实际的 AQL 语句开始工作。
- 另外,请注意外部 RETURN 语句中的 FLATTEN 函数,这是必需的,因为在第一个循环中,我们为每个定义的排序值获取结果数组。这些都必须扁平化到同一级别,以便作为唯一结果集处理(而不是许多封装的小结果集)。
/* Define a dummy collection-array to work with */
LET a = [
{
"_id": "a/384072353674",
"_key": "384072353674",
"_rev": "384073795466",
"sort": 2
},
{
"_id": "a/384075040650",
"_key": "384075040650",
"_rev": "384075827082",
"sort": 3
},
{
"_id": "a/384077137802",
"_key": "384077137802",
"_rev": "384078579594",
"sort": 4
},
{
"_id": "a/384067504010",
"_key": "384067504010",
"_rev": "384069732234",
"sort": 1
},
{
"_id": "a/384079497098",
"_key": "384079497098",
"_rev": "384081004426",
"sort": 5
}
]
/* Define the custom sort values */
LET cSort = [5,3,1]
/* Gather the results of each defined sort value query into definedSortResults */
LET definedSortResults = (
FOR u in cSort
LET d = (
FOR docs IN `a`
FILTER docs.`sort` == u
RETURN docs
)
RETURN d
)
/* Append the the result of the last (all the non-defined sort values) query to the results of the definedSortResults into the output array */
LET output = (
APPEND (definedSortResults, (
FOR docs IN `a`
FILTER docs.`sort` NOT IN cSort
RETURN docs
)
)
)
/* Finally FLATTEN and RETURN the output variable */
RETURN FLATTEN(output)
2) 一种不同的方法是,使用 JavaScript 中编写的函数扩展 AQL,这基本上会执行与上述相同的步骤。
当然,您也可以在 ArangoDB 的 GitHub 页面上提出功能请求,也许 ArangoDB 的好心人会考虑将其包含在内。 :)
希望对您有所帮助
我认为应该可以使用 POSITION
AQL 函数,它可以 return 数组中元素的位置
FOR i IN [ 1, 2, 3, 4, 5 ] /* what to iterate over */
SORT POSITION([ 2, 4, 1, 5, 3 ], i, true) /* order to be returned */
RETURN i
这将 return:
[ 2, 4, 1, 5, 3 ]
更新:我原来的答案包括CONTAINS
AQL函数,但是,它应该是POSITION
!
我想按特定顺序按字段排序,比方说 2,4,1,5,3。
在 MySQL 中我可以使用 ORDER BY FIELD(id,2,4,1,5,3)
。
ArangoDB 有什么等价物吗?
遗憾的是,目前没有直接对应的方法。
但是,有一些方法可以自己完成。
1) 通过构建AQL查询: 该查询将 运行 通过您的排序值数组并查询数据库以获取每个定义的值。然后将这些结果中的每一个添加到最终输出数组中。
请注意,这确实会降低性能,因为每个值都有一个查询。如果你只定义几个,我想这是可以容忍的,但如果你必须定义例如几十或几百,它将导致 n+1 查询(其中 n 是自定义排序值的数量)。
“+1”是最后一个查询,它应该获取所有其他值的结果,这些值未在您的自定义排序数组中定义,并将它们附加到您的输出数组。
这看起来像下面的代码片段,您可以将其复制到 AQL 编辑器中并 运行 它。
片段注释:
- 我首先创建一个数组,它代表我们的集合 会查询。
- 然后我正在设置定义的排序值。
- 之后,实际的 AQL 语句开始工作。
- 另外,请注意外部 RETURN 语句中的 FLATTEN 函数,这是必需的,因为在第一个循环中,我们为每个定义的排序值获取结果数组。这些都必须扁平化到同一级别,以便作为唯一结果集处理(而不是许多封装的小结果集)。
/* Define a dummy collection-array to work with */
LET a = [
{
"_id": "a/384072353674",
"_key": "384072353674",
"_rev": "384073795466",
"sort": 2
},
{
"_id": "a/384075040650",
"_key": "384075040650",
"_rev": "384075827082",
"sort": 3
},
{
"_id": "a/384077137802",
"_key": "384077137802",
"_rev": "384078579594",
"sort": 4
},
{
"_id": "a/384067504010",
"_key": "384067504010",
"_rev": "384069732234",
"sort": 1
},
{
"_id": "a/384079497098",
"_key": "384079497098",
"_rev": "384081004426",
"sort": 5
}
]
/* Define the custom sort values */
LET cSort = [5,3,1]
/* Gather the results of each defined sort value query into definedSortResults */
LET definedSortResults = (
FOR u in cSort
LET d = (
FOR docs IN `a`
FILTER docs.`sort` == u
RETURN docs
)
RETURN d
)
/* Append the the result of the last (all the non-defined sort values) query to the results of the definedSortResults into the output array */
LET output = (
APPEND (definedSortResults, (
FOR docs IN `a`
FILTER docs.`sort` NOT IN cSort
RETURN docs
)
)
)
/* Finally FLATTEN and RETURN the output variable */
RETURN FLATTEN(output)
2) 一种不同的方法是,使用 JavaScript 中编写的函数扩展 AQL,这基本上会执行与上述相同的步骤。
当然,您也可以在 ArangoDB 的 GitHub 页面上提出功能请求,也许 ArangoDB 的好心人会考虑将其包含在内。 :)
希望对您有所帮助
我认为应该可以使用 POSITION
AQL 函数,它可以 return 数组中元素的位置
FOR i IN [ 1, 2, 3, 4, 5 ] /* what to iterate over */
SORT POSITION([ 2, 4, 1, 5, 3 ], i, true) /* order to be returned */
RETURN i
这将 return:
[ 2, 4, 1, 5, 3 ]
更新:我原来的答案包括CONTAINS
AQL函数,但是,它应该是POSITION
!