Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include score in Morphia full text search

I am trying to use the MongoDB full text indices in Morphia. I need to return the score for each documents as well as have the results sorted. This is what my query looks like without Morphia:

   db.getCollection('disease').find( { $text: { $search: "brain" } }, 
                                     { score: { $meta: "textScore" } } )
                              .sort( { score: { $meta: "textScore" } } )

This works correctly and returns hits sorted by score.

I also can do this using the MongoDB Java driver directly without Morphia.

    // search with the Java driver
    BasicDBObject textSearch = new BasicDBObject("$search", "brain");
    BasicDBObject search = new BasicDBObject("$text", textSearch);

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

    List<DBObject> diseases = collection.find(search, score).sort(score).toArray();
    Assert.assertEquals(2, diseases.size());
    Assert.assertEquals("brain", diseases.get(0).get("name"));
    Assert.assertEquals("benign-brain", diseases.get(1).get("name"));

I can't figure out how to accomplish the same thing in Morphia. Here is the example from the Morphia documentation (http://mongodb.github.io/morphia/1.0/guides/querying/#text-searching):

List<Greeting> good = datastore.createQuery(Greeting.class)
                             .search("good")
                             .order("_id")
                             .asList();
Assert.assertEquals(4, good.size());

The example does not return score and is ordering by "_id". I don't see any way to handle the $meta operator in Morphia. Has anyone done something similar?

like image 544
Chuck M Avatar asked Nov 01 '22 02:11

Chuck M


1 Answers

Because Morphia maps back to your type, the only way to expose the score in this situation would be to add a score field to your entity type and map it back to that field. This isn't awesome because it starts to pollute your business types with database metadata fields. You could always try mapping back out a special value object type containing whatever metadata you'd like. That would at least keep your business objects free of this metadata.

like image 66
evanchooly Avatar answered Nov 08 '22 11:11

evanchooly