Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I pass parameters to Mongodb map/reduce in Java?
    primarykey
    data
    text
    <p>I have some data like this:</p> <pre><code>{id: 1, text: "This is a sentence about dogs", indices: ["sentence", "dogs"]} {id: 2, text: "This sentence is about cats and dogs", indices: ["sentence", "cats", "dogs"]} </code></pre> <p>Where I have manually extracted key terms from the text and stored them as indices. I want to be able to do a search and order the results with the most matching indices. So for this example, I would like to be able to pass "cats" and "dogs" and get both objects returned, but id=2 should be first with score=2.</p> <p>I first tried to use the DBCollection.group function</p> <p>{<code>public DBObject group(DBObject key, DBObject cond, DBObject initial, String reduce, String finalize)</code>}</p> <p>But I don't see a way to send parameters. I tried:</p> <pre><code>key: {id: true}, cond: {"indices" $in ['cats', 'dogs']}, initial: {score: 0} reduce: function(doc, out){ out.score++; } </code></pre> <p>but obviously this will just return a count of 1 for each of the 2 objects.</p> <p>I realised that I could send the keyword parameters as part of the initial config of the reduced object.</p> <pre><code>final List&lt;String&gt; targetTerms = Arrays.asList("dogs", "cats"); final Datastore ds = …. final DBCollection coll = ds.getCollection(Example.class); BasicDBObject key = new BasicDBObject("_id", true); BasicDBObject cond = new BasicDBObject(); cond.append("indices", new BasicDBObject("$in", targetTerms)); BasicDBObject initial = new BasicDBObject(); initial.append("score", 0); initial.append("targetTerms", targetTerms); String reduce = "function (obj, prev) { " + " for (i in prev.targetTerms) {" + " targetTerm = prev.targetTerms[i];"+ " for (j in obj.indices) {" + " var index = obj.indices[j];"+ " if (targetTerm === index) prev.score++;" + " }" + " }" + "}"; String fn = null; final BasicDBList group = (BasicDBList) coll.group(key, cond, initial, reduce, fn); </code></pre> <p>I get results like this:</p> <pre><code>{ "_id" : { "$oid" : "4dcfe16c05a063bb07ccbb7b"} , "score" : 1.0 , "targetTerms" : [ "virtual" , "library"]} { "_id" : { "$oid" : "4dcfe17d05a063bb07ccbb83"} , "score" : 2.0 , "targetTerms" : [ "virtual" , "library"]} </code></pre> <p>This got me the score values that I wanted, and I am able to narrow down the entries to be processed with more specific conditional rules.</p> <p>So I have a few questions:</p> <ol> <li>Is this a good way to send "parameters" to the group action's reduce function?</li> <li>Is there a way to sort (and perhaps limit) the output inside mongodb before returning to the client?</li> <li>Will this break on sharded Mongodb instances?</li> </ol>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload