У меня есть такие данные:
{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"]}
Где я вручную извлек ключевые термины из текста и сохранил их как индексы. Я хочу быть в состоянии сделать поиск и упорядочить результаты с наиболее подходящими показателями. Так что для этого примера я хотел бы иметь возможность передавать «кошки» и «собаки» и возвращать оба объекта, но id = 2 должен быть первым со счетом = 2.
Сначала я попытался использовать функцию DBCollection.group
{public DBObject group(DBObject key,
DBObject cond,
DBObject initial,
String reduce,
String finalize)
}
Но я не вижу способа отправки параметров. Я попробовал:
key: {id: true},
cond: {"indices" $in ['cats', 'dogs']},
initial: {score: 0}
reduce: function(doc, out){ out.score++; }
но очевидно, что это просто вернет счетчик 1 для каждого из 2 объектов.
Я понял, что могу отправить параметры ключевого слова как часть начальной конфигурации сокращенного объекта.
final List<String> 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);
Я получаю такие результаты:
{ "_id" : { "$oid" : "4dcfe16c05a063bb07ccbb7b"} , "score" : 1.0 , "targetTerms" : [ "virtual" , "library"]}
{ "_id" : { "$oid" : "4dcfe17d05a063bb07ccbb83"} , "score" : 2.0 , "targetTerms" : [ "virtual" , "library"]}
Это дало мне значения баллов, которые я хотел, и я могу сузить записи, которые нужно обработать, с более конкретными условными правилами.
Итак, у меня есть несколько вопросов:
- Является ли это хорошим способом отправки "параметров" в функцию уменьшения действия группы?
- Есть ли способ отсортировать (и, возможно, ограничить) вывод внутри mongodb перед возвратом к клиенту?
- Будет ли это ломаться на осколках экземпляров Mongodb?