2015-12-12 3 views
5

Ich habe ein Problem mit Java API für MongoDB. Ich habe eine Abfrage mit Robomongo erstellt:MongoDB Java API: Volltextsuche

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

Nun möchte Ich mag die gleiche Abfrage API mit Java erstellen:

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

Das Problem ist, dass dieser Code funktioniert nicht. Die Abfrage:

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

funktioniert einwandfrei. Nach dem Anhängen des zweiten Teils werden alle Ergebnisse unsichtbar. Was mehr ist, diese Zeile:

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

wirft MongoException (badValue schlechte Sorte Spezifikation). Wenn ich sort() Methodenaufruf lösche, ist die Exception nicht vorhanden, aber ich habe noch keine Ergebnisse (wenn ich "score" angehängt habe).

Ich habe eine Lösung für dieses Problem gefunden, aber mit Spring. Ich möchte keine anderen Bibliotheken verwenden. Außerdem bin ich ein Anfänger in MongoDB. Danke für deine Hilfe und Zeit, Prost.


UPDATE. Problem gelöst. Anhängen von "score" an query searchCommand, das als erster Parameter von find() übergeben wurde, ist falsch. „Score“ sollte in getrenntem DBObject als zweiten Parameter von find() Methode übergeben werden, wie folgt:

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

Antwort

6

Sie haben ganz in der Nähe, mit dem, was Sie versucht haben.

Beachten Sie, dass in,

db.collection.find(
    {$text : {$search : "\"expression\" keyword"}}, 
    {score : {$meta : "textScore"}} 
).sort({score : {$meta : "textScore"}}) 
  • {$text : {$search : "\"expression\" keyword"}} - ist der query Teil.

  • {score : {$meta : "textScore"}} - ist der projection Teil.

In dem, was Sie versucht haben, mit dem Java Treiber zu implementieren,

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

würde produzieren am Ende,

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

, die nicht gleichbedeutend mit der nativen Abfrage ist. Sogar die intendierteprojection Erklärung war ein Teil der query selbst.

anzumerken, dass dies für ein Feld suchen endet namens score, da es nun ein Teil der query und nicht die projection worden ist.

Sie können ganz einfach ändern Sie Ihre DBObject Fällen ist es ein Teil des projection Parameter zu machen und es funktionieren würde:

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

Thank you very much :) Es scheint, dass ich mein Problem ein paar Momente entdeckt, bevor Sie Antwort. Wie auch immer, danke für die umfassende Erklärung. – bargro