使用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)
答案 0 :(得分:1)
好吧,我发现了问题。正如我在对该问题的评论中提到的那样,当您调用sort
时,MongoDB驱动程序开始使用meta-query operators而不仅仅是简单的对象查询,就像您通常那样。
例如,没有排序的简单查询将如下所示:
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
(这允许我在查询中添加元运算符)以及尝试取消&#34;取消&#34;自动生成(和错误)查询,如下所示:
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 ) );
...
现在上面的所有测试都通过了!
显然,这是一个可怕的黑客,希望MongoDB团队尽快修复Java客户端。与此同时,我至少可以让它发挥作用。
我曾尝试在Java Driver JIRA中发布错误,但我无法了解如何注册。
编辑2
实际上,刚发现我可以注册并创建一张票:JAVA-1176
**编辑3 **
刚刚与MongoDB团队一起发现,最新版本的Fongo(编写本文时为1.4.5)和Java驱动程序版本2.11.4不再存在此问题。
不幸的是,由于兼容性问题,我们还不能使用Java驱动程序的最新版本(2.12.0),但上述版本不会出现问题!