2

使用sort. 我希望查询的结果与我没有使用sort时完全相同,当然,除了结果应该是排序的,但发生的情况是使用时sort我什么也得不到。

这是重现问题的完整示例:

DB db = fongo.getDB( "something" );
DBCollection collection = db.getCollection( "what" );
collection.insert( new BasicDBObject( "hello", 4 ) );
collection.insert( new BasicDBObject( "hello", 2 ) );
collection.insert( new BasicDBObject( "hello", 1 ) );
collection.insert( new BasicDBObject( "hello", 3 ) );

final DBCursor sorted = collection
    .find( new BasicDBObject( "hello", new BasicDBObject( "$exists", true ) ) )
    .sort( new BasicDBObject( "hello", 1 ) )
    .limit( 10 );

final DBCursor notSorted = collection
    .find( new BasicDBObject( "hello", new BasicDBObject( "$exists", true ) ) )
            .limit( 10 );

// both asserts below work!
assertThat( notSorted.size(), is( 4 ) );
assertThat( sorted.size(), is( 4 ) );

List<DBObject> notSortedAsList = notSorted.toArray();
List<DBObject> sortedAsList = sorted.toArray();

assertThat( notSortedAsList.size(), is( 4 ) );
assertThat( sortedAsList.size(), is( 4 ) ); // << BREAKS HERE!!!!
assertThat( sortedAsList.stream().map( obj -> obj.get( "hello" ) )
    .collect( Collectors.toList() ), is( Arrays.asList( 1, 2, 3, 4 ) ) );

如您所见,notSortedAsList列表包含 4 个元素,正如预期的那样,但是sortedAsList是空的!唯一的区别是后者是从包含sort.

除非我做错了什么,否则这似乎是 MongoDB Java 驱动程序中的一个错误,即使它也可能与Fongo我使用它来测试它有关。

关于发生了什么的任何想法?

编辑

这是由上面显示的包含排序的查询生成的:

find({ "query" : { "hello" : { "$exists" : true}} , "orderby" : { "hello" : 1}}, null).skip(0).limit(10)

如果没有sort,查询如下所示:

find({ "hello" : { "$exists" : true}}, null).skip(0).limit(10)

我也尝试过执行以下查询:

final DBCursor sorted = collection
    .find( new BasicDBObject( "hello", new BasicDBObject( "$exists", true ) ) )
    .addSpecial( "$orderby", new BasicDBObject( "hello", 1 ) )
    .limit( 10 );

然后生成的查询是:

find({ "$orderby" : { "hello" : 1} , "query" : { "hello" : { "$exists" : true}}}, null).skip(0).limit(10)

两者都有相同的结果,尽管第一次使用orderby和第二次使用$orderby(如此处建议:http: //docs.mongodb.org/manual/reference/operator/meta/orderby/#op._S_orderby

4

1 回答 1

1

嗯,我发现了问题。正如我在对该问题的评论中提到的,当您调用sortMongoDB 驱动程序时,开始使用元查询运算符,而不是像通常那样使用简单的对象查询。

例如,没有排序的简单查询如下所示:

find({ "hello" : { "$exists" : true}}, null)

以上将找到包含名为"hello".

但是,当您使用 时sort,查询如下所示:

find({ "query" : { "hello" : { "$exists" : true}} , "orderby" : { "hello" : 1}}, null)

这是错误的,因为它会匹配一个文档,该文档包含一个名为"query"上述值的字段,以及一个名为"orderby"...

正确的查询应该是:

find({ "$orderby" : { "hello" : 1} , "$query" : { "hello" : { "$exists" : true}}}, null)

唯一的区别是$使键成为元运算符。

为了证实这个假设,我修改了要使用的代码addSpecial(它允许我将元运算符添加到查询中)并尝试“取消”自动生成的(和错误的)查询,如下所示:

final DBCursor sorted = collection
    .find( )
    .addSpecial( "$orderby", new BasicDBObject( "hello", 1 ) )
    .addSpecial( "$query", new BasicDBObject( "hello", new BasicDBObject( "$exists", true ) ) )
    .limit( 10 );

因为这仍然会"query"在查询中保留错误的运算符,所以我必须在我的文档中添加一个query字段以使其最终起作用:

collection.insert( new BasicDBObject( "hello", 4 ).append( "query", 1 ) );
...

现在上面的所有测试都通过了!

显然,这是一个可怕的 hack,希望 MongoDB 团队尽快修复 Java 客户端。与此同时,我至少可以让它工作。

我试图在Java Driver JIRA中发布一个错误,但我找不到如何注册。

编辑 2

实际上,刚刚发现我可以注册并创建票:JAVA-1176

** 编辑 3 **

刚刚与 MongoDB 团队一起发现,最新版本的 Fongo(撰写本文时为 1.4.5)和 Java 驱动程序版本 2.11.4 不再存在此问题。

不幸的是,由于兼容性问题,我们还不能使用最新版本(2.12.0)的Java驱动程序,但以上版本不会出现问题!

于 2014-04-23T13:40:47.283 回答