从 MongoDB 排序规则获取不需要的输出

Posted

技术标签:

【中文标题】从 MongoDB 排序规则获取不需要的输出【英文标题】:Getting unwanted output from MongoDB collation 【发布时间】:2020-08-18 20:33:17 【问题描述】:

我正在尝试以“a.b.c”的形式对发布版本进行排序

我正在使用 mongo-java-driver

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.8.0</version>
</dependency>

我已经使用排序规则创建了索引:


    "v" : 2,
    "key" : 
            "version" : 1
    ,
    "name" : "version_1",
    "ns" : "db.sysversion",
    "collation" : 
            "locale" : "en",
            "caseLevel" : false,
            "caseFirst" : "off",
            "strength" : 3,
            "numericOrdering" : true,
            "alternate" : "non-ignorable",
            "maxVariable" : "punct",
            "normalization" : false,
            "backwards" : false,
            "version" : "57.1"
    

我已经用java驱动实现了聚合查询:

Collation collation = Collation.builder().locale("en").numericOrdering(true).build();

ArrayList<Document> response = new ArrayList<>();

ArrayList<Bson> aggregate = new ArrayList<Bson>(Arrays.asList(
  match(gt("version", "1.9.4")), sort(descending("version")),
  project(fields(include("version"), exclude("_id")))
));

this.database.getCollection(sysversion).aggregate(aggregate).collation(collation).into(response);

我正在将文档中的列表作为 API 响应返回。

return new Document("version", response);

但我得到的输出是:

 "version" : [ "version" : "\u000f\u0003\b\u000f\f\b\u000f\u0003\u0001\t\u0001\t" ,  "version" : "\u000f\u0003\b\u000f\f\b\u000f\u0002\u0001\t\u0001\t" ] 

当我尝试使用 Mongo shell 时,我得到以下输出 (这是正确的)


  version:[
    
    "version" : "1.10.1"
    ,
    
    "version" : "1.10.0"
    
  ]

我的 Java 代码有什么问题?是版本号还是代码错误?

任何帮助将不胜感激。

【问题讨论】:

在您的response.forEach(System.out::println); 中试试这个:而不是System.out::println 使用doc -&gt; System.out.println(doc.toJson()) 不,这是从邮递员那里获取的 API 响应。所以,问题不在于打印。 MongoDB 以 UTF-8 存储字符串,不正确的输出看起来有点像 unicode。 True @Joe,它正在返回 Unicode 值,但我在 shell 查询中得到了正确的输出。 Mongo-Java-Driver 面临这个问题。 【参考方案1】:

发现问题

我调试了这个问题,发现排序规则使用normalization 对查询响应进行编码。默认情况下,该值为false。因此,shell 查询返回了正确的输出。

但在 Mongo-java-Driver 中,它将 normalization 设置为 true(默认情况下)。

将生成器更新为 false 的标准化:

Collation collation = Collation.builder().locale("en").numericOrdering(true).normalization(false).build();
ArrayList<Document> response = new ArrayList<>();

ArrayList<Bson> aggregate = new ArrayList<Bson>(Arrays.asList(
  match(gt("version", "1.9.4")), sort(descending("version")),
  project(fields(include("version"), exclude("_id")))
));

this.database.getCollection(sysversion).aggregate(aggregate).collation(collation).into(response);

这解决了我的问题。

【讨论】:

以上是关于从 MongoDB 排序规则获取不需要的输出的主要内容,如果未能解决你的问题,请参考以下文章

用Java实现桶排序算法

mongodb排序规则不适用于facet阶段的insinde聚合

如何使用排序从输出文件 1 中的 F1 和 F2 中获取匹配记录,以及从输出文件 2 中的 F2 中获取不匹配记录

[华为]字符串排序

字符串排序

36:字符串排序SortString