简体   繁体   English

ArangoDB自定义排序顺序

[英]ArangoDB custom sort order

I would like to sort by a field in a specific order, lets say 2,4,1,5,3. 我想按特定顺序按字段排序,比如说2,4,1,5,3。

In MySQL I could use ORDER BY FIELD(id,2,4,1,5,3) . 在MySQL中,我可以使用ORDER BY FIELD(id,2,4,1,5,3)

Is there anything equivalent for ArangoDB? ArangoDB有什么等效功能吗?

I think it should be possible to use the POSITION AQL function, which can return the position of an element inside an array 我认为应该可以使用POSITION AQL函数,该函数可以返回数组中元素的位置

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

This will return: 这将返回:

[ 2, 4, 1, 5, 3 ]

Update : my original answer included the CONTAINS AQL function, however, it should be POSITION ! 更新 :我的原始答案包括CONTAINS AQL函数,但是应该是POSITION

Unfortunately, there is no direct equivalent for that, at the moment. 不幸的是,目前尚无直接等效的方法。

However, there are ways to accomplish that by yourself. 但是,有一些方法可以自己完成。

1) By constructing an AQL query: The query would run through your sort value array and query the DB for every defined value. 1)通过构造一个AQL查询:该查询将遍历您的排序值数组,并向数据库查询每个定义的值。 Each of those results would then be added to the final output array. 这些结果中的每一个都将被添加到最终的输出数组中。

Mind you, that this does have a performance penalty, because there is one query for every value. 请注意,这确实会降低性能,因为每个值都有一个查询。 If you are defining only a few ones, I guess it will be tolerable, but if you have to define for example tens or hundreds, it will lead to n+1 queries (where n is the number of custom sorted values). 如果您仅定义几个,我猜它是可以容忍的,但是如果您必须定义例如几十个或几百个,它将导致n + 1个查询(其中n是自定义排序值的数量)。

The "+1" is the last query, which should get the result of all the other values, which are not defined in your custom sort array and also append these to your output array. “ +1”是最后一个查询,它应获取自定义排序数组中未定义的所有其他值的结果,并将它们附加到输出数组中。

That would look like the following snippet, which you can copy into your AQL Editor and run it. 看起来像以下代码片段,您可以将其复制到AQL编辑器中并运行它。

Notes for the snippet: 该代码段的注意事项:

  • I am first creating an array, which would represent the collection we would query. 我首先创建一个数组,该数组代表我们要查询的集合。
  • Then I am setting the defined sort values. 然后我设置定义的排序值。
  • After that, the actual AQL statement does its job. 之后,实际的AQL语句完成其工作。
  • Also, note the FLATTEN function at the outer RETURN statement, which is required, because in the first loop we are getting result arrays for each defined sort value. 另外,请注意在外部RETURN语句处的FLATTEN函数,这是必需的,因为在第一个循环中,我们将获得每个定义的排序值的结果数组。 These have all to be flatten down to the same level in order to be processed as a unique result set (instead of many encapsulated small ones). 为了将它们作为唯一的结果集(而不是许多封装的小结果集)进行处理,所有这些都必须放平到同一级别。

 /* 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) A different approach would be, to extend AQL with a function written in JavaScript, that would essentially do the same steps as above. 2)一种不同的方法是,用JavaScript编写的函数扩展AQL,该方法实质上将执行与上述相同的步骤。

Of course, you could also open up a feature request on ArangoDB's GitHub Page, and maybe the nice folks at ArangoDB will consider it for inclusion. 当然,您也可以在ArangoDB的GitHub Page上打开功能请求,也许ArangoDB的好伙伴会考虑将其包含在内。 :) :)

Hope that helps 希望能有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM