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

Fongo私が何か間違ったことをしていない限り、これはMongoDB Javaドライバーのバグである可能性がありますが、これをテストするために使用しているため、関連する可能性もあります.

何が起こっているかについてのアイデアはありますか??

編集

これは、上記の並べ替えを含むクエリによって生成されるものです。

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と 2 番目の使用は同じです$orderby(ここで提案されているように: http://docs.mongodb.org/manual/reference/operator/meta/orderby/#op._S_orderby ) 。

4

1 に答える 1

1

さて、私は問題を見つけました。質問に対するコメントで述べたようにsort、MongoDB ドライバーを呼び出すと、通常の単純なオブジェクト クエリではなく、メタクエリ演算子の使用が開始されます。

たとえば、並べ替えを行わない単純なクエリは次のようになります。

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 ) );
...

これで、上記のすべてのテストに合格しました!

明らかに、これは恐ろしいハッキングであり、MongoDB チームができるだけ早く Java クライアントを修正してくれることを願っています。それまでの間、少なくともこれを機能させることができます。

Java Driver JIRAでバグを発行しようとしましたが、登録方法がわかりませんでした。

編集2

実は、サインアップできることを知り、チケットを作成しました: JAVA-1176

** 編集 3 **

MongoDB チームの調査によると、Fongo の最新バージョン (執筆時点では 1.4.5) と Java ドライバー バージョン 2.11.4 では、この問題はもう存在しないことがわかりました。

残念ながら、Java ドライバーの最新バージョン (2.12.0) は互換性の問題でまだ使用できませんが、上記のバージョンでは問題は発生しません。

于 2014-04-23T13:40:47.283 に答える