我为所有实体提交了审核:
createDate
updateDate
我始终在实体创建期间初始化createDate
,但updateDate
可以包含NULL
,直到第一次更新。
我必须在这些字段上实现排序功能。
使用createDate
一切正常,但updateDate
我遇到了问题。
如果在降序排序期间updateDate
中有一组混合的NULL和Dates,我首先得到NULL,这不是我在这里期待的东西。
据我所知,根据Neo4j文档,这是一种期待的行为 - When sorting the result set, null will always come at the end of the result set for ascending sorting, and first when doing descending sort. 但我现在还不知道如何从用户角度实现正确的排序,用户将看到最新的排序列表顶部的更新文档。前段时间我甚至为此功能创建了GitHub问题https://github.com/opencypher/openCypher/issues/238
我可以在这里看到一个解决方法 - 在实体创建过程中同时填充updateDate
和createDate
,但我真的很讨厌这个解决方案。
是否还有其他解决方案才能正确执行此任务?
答案 0 :(得分:1)
您可以尝试使用coalesce() function。它将返回传递给它的表达式列表中的第一个非null值。
MATCH (n:Node)
RETURN n
ORDER BY coalesce(n.updateDate, 0) DESC
修改强>
来自评论:
在数据库级别上它是这样的:“updateDate”: “2017-09-07T22:27:11.012Z”。在SDN4级别上它是Java - java.util.Date类型
在这种情况下,您可以将0更改为表示开始时间常量的日期(例如“1970-01-01T00:00:00.000Z”)。
MATCH (n:Node)
RETURN n
ORDER BY coalesce(n.updateDate, "1970-01-01T00:00:00.000Z") DESC
答案 1 :(得分:1)
当updateDate为空时,我只使用createDate作为updateDate:
MATCH (n:Node)
RETURN n
ORDER BY coalesce(n.updateDate, n.createDate) DESC
答案 2 :(得分:1)
您可能需要考虑将ISO 8601时间戳字符串存储为(毫秒)整数。这可能会使涉及日期时间操作的大多数查询更有效(甚至可能),并且与等效字符串相比也会占用更少的数据库空间。
进行转换的一种方法是使用APOC函数apoc.date.parse。例如,这会将2017-09-07T22:27:11.012Z
转换为整数(以毫秒为单位):
apoc.date.parse('2017-09-07T22:27:11.012Z', 'ms', "yyyy-MM-dd'T'HH:mm:ss.SSSX")
通过对数据模型的此更改,您还可以在节点创建时将updateDate
初始化为0。这样可以避免使用COALESCE(n.updateDate, 0)
进行排序(如@Bruno Peres所建议的那样),
并且0
值将用作指示节点从未更新。
(但缺点是所有节点都有updateDate
属性,即使是那些从未更新的属性。)