2015-12-12 30 views
5

Mam problem z używaniem API Java dla MongoDB. Stworzyłem zapytanie korzystając Robomongo:MongoDB Java API: Wyszukiwanie pełnotekstowe

db.collection.find(
    {$text : {$search : "\"expression\" keyword"}}, 
    {score : {$meta : "textScore"}} 
).sort({score : {$meta : "textScore"}}) 

Teraz chciałbym stworzyć taką samą kwerendę używając Java API:

DBObject searchCommand = new BasicDBObject(
    "$text", new BasicDBObject("$search", "\"expression\" keyword") 
).append(
    "score", new BasicDBObject("'$meta'", "textScore") 
); 

DBObject sorting = new BasicDBObject(
    "score", new BasicDBObject("'$meta'", "textScore") 
); 

DBCursor result = collection.find(searchCommand).sort(sorting); 

Problemem jest to, że ten kod nie działa. Zapytanie:

DBObject searchCommand = new BasicDBObject(
    "$text", new BasicDBObject("$search", "\"expression\" keyword") 
); 

działa idealnie. Po dołączeniu drugiej części wszystkie wyniki stają się niewidoczne. Co więcej, linia ta:

DBCursor result = collection.find(searchCommand).sort(sorting); 

wyrzuca MongoException (BadValue). Po usunięciu wywołania metody sort() wyjątek nie występuje, ale nadal nie mam żadnych wyników (jeśli dodam "wynik").

Znalazłem rozwiązanie tego problemu, ale za pomocą Spring. Nie chciałbym używać żadnych innych bibliotek. Ponadto, jestem początkujący w MongoDB. Dziękuję za pomoc i czas, okrzyki.


AKTUALIZACJA. Problem rozwiązany. Dołączanie "wyniku" do zapytania searchCommand przekazanego jako pierwszy parametr find() jest niepoprawne. „Score” powinny zostać przekazane w oddzielnym dbobject jako drugi parametr metody find() w następujący sposób:

DBObject search = new BasicDBObject(
    "$text", new BasicDBObject("$search", "\"expression\" keyword") 
); 

DBObject project = new BasicDBObject(
    "score", new BasicDBObject("$meta", "textScore") 
); 

DBObject sorting = new BasicDBObject(
    "score", new BasicDBObject("$meta", "textScore") 
); 

DBCursor result = collection.find(search, project).sort(sorting); 

Odpowiedz

6

Masz naprawdę blisko, z czego próbowaliśmy.

Należy zauważyć, że,

db.collection.find(
    {$text : {$search : "\"expression\" keyword"}}, 
    {score : {$meta : "textScore"}} 
).sort({score : {$meta : "textScore"}}) 
  • {$text : {$search : "\"expression\" keyword"}} - to część query.

  • - jest częścią projection.

W co próbowali realizować za pomocą sterownika Java,

DBObject searchCommand = new BasicDBObject(
    "$text", new BasicDBObject("$search", "\"expression\" keyword") 
).append(
    "score", new BasicDBObject("'$meta'", "textScore") 
); 

skończy się produkcją,

{$text:{$search:"\"expression\" keyword"},"score":{"meta":"textscore"}} 

co nie jest równoznaczne z natywnym zapytania. Nawet instrukcja miała być częścią samej query.

zauważyć, że to kończy się patrząc na polu o nazwie score, ponieważ stał się częścią nieprojectionquery i .

można łatwo zmodyfikować instancji DBObject, aby to część parametru projection i to działa:

DBObject findCommand = new BasicDBObject(
    "$text", new BasicDBObject("$search", "keyword") 
); 

DBObject projectCommand = new BasicDBObject(
    "score", new BasicDBObject("$meta", "textScore")); 

DBObject sortCommand = new BasicDBObject(
    "score", new BasicDBObject("$meta", "textScore") 
); 
DBCursor result = collection.find(
            findCommand ,projectCommand) 
            .sort(sortCommand); 
+1

Dziękuję bardzo :) Wydaje się, że odkryłem mój problem kilka chwil przed swój odpowiedź. W każdym razie, dziękuję za wyczerpujące wyjaśnienie. – bargro