为什么Java N1QL中的ORDER BY无法按预期工作

问题描述

当我运行SELECT * FROM projects ORDER BY createdAt desc时,该查询在Couchbase Web UI结果中按应有的顺序排列,但在Java中则不然。

Java代码

@Override
    public List<Project> getAllProjects(String requestedOrder,Integer page,Integer pageOffset) {
        String statement = "SELECT projects.* FROM projects ORDER BY $requestedOrder DESC OFFSET $offset LIMIT $pageOffset";
        QueryOptions queryOptions = queryOptions().parameters(
                JsonObject.create().put("offset",(page - 1) * pageOffset)
                        .put("pageOffset",pageOffset)
                        .put("requestedOrder",requestedOrder));
        QueryResult queryResult = couchbaseCluster.query(statement,queryOptions);
        return queryResult.rowsAs(Project.class);
    }

Web UI结果

[
  {
    "projects": {
      "createdAt": 1603804921950,"name": "Third Project",...
    }
  },{
    "projects": {
      "createdAt": 1603804915827,"name": "Second Project",{
    "projects": {
      "createdAt": 1603804909410,"name": "First Project"
      ...
    }
  }
]

Java SDK结果

[
  {
    "name": "Second Project","createdAt": "2020-10-27T13:21:55.827+00:00",...
  },{
    "name": "Third Project","createdAt": "2020-10-27T13:22:01.950+00:00",{
    "name": "First Project","createdAt": "2020-10-27T13:21:49.410+00:00",...
  }
]

当我将语句更改为此时,它可以正确排序,但为什么不能使用put方法正确地排序。

String statement = "SELECT projects.* FROM projects ORDER BY " + requestedOrder + " DESC OFFSET $offset LIMIT $pageOffset";

解决方法

String statement = "SELECT projects.* FROM projects ORDER BY $requestedOrder DESC OFFSET $offset LIMIT $pageOffset";

在上述查询中,您将ORDER BY表达式作为命名参数(即值)传递。对于查询中的所有文档,该值将是恒定的且相同。按相同的值排序为NOOP,即它可能不排序任何内容。

ORDER BY表达式必须取决于文档的字段。每次如果您需要不同的字段,则必须使用不同的查询。

注意:JSON的架构较少,没有字段的物理位置。与某些RDBS数据库使用投影字段位置进行排序相比,ORDER BY数字将被视为常量。

如果$ requestedOrder不是嵌套字段,请尝试使用以下内容替换查​​询字符串。 $ requestedOrder必须计算为字符串,并且必须是文档的字段(非嵌套)。示例$ requestedOrder =“ createdAt”排序执行期间将评估p.createdAt(即与ORDER BY p.createdAt相同)

 String statement = "SELECT p.* FROM projects AS p ORDER BY p.[$requestedOrder] DESC OFFSET $offset LIMIT $pageOffset";