MongoDB получает количество совпадений командой $ in - PullRequest
0 голосов
/ 03 июля 2018

Определение

Я создаю поисковое приложение, а mongo db используется для хранения поисковой информации. Это пример набора данных коллекции "Ресурс".

{
   _id:"5b3b84e02360a26f9a9ae96e",
   name:"Advanced Java",
   keywords:[
      "java", "thread", "state", "public", "void"
   ] 
},
{
   _id:"5b3b84e02360a26f9a9ae96f",
   name:"Java In Simple",
   keywords:[
      "java", "runnable", "thread", "sleep", "array"
   ]
}

Содержит названия книг и наиболее часто встречающиеся слова (в массиве ключевых слов) каждой из них. Я использую весенние рамки с шаблоном Монго. Если я запускаю ниже код,

MongoOperations mongoOperations = new MongoTemplate(new MongoClient("127.0.0.1", 27017), "ResourceDB");
Query query = new Query(where("keywords").in("java", "thread", "sleep"));
List<Resource> resources = mongoOperations.find(query, Resource.class);

Это приводит к "Advanced Java" и "Java In Simple", и все в порядке.

Задача

Но в моем случае они мне нужны по порядку. Потому что «Java In Simple» соответствует 3 словам, а «Advanced Java» соответствует только 2 словам. Таким образом, наиболее подходящей книгой должна быть «Java In Simple», и она должна быть первой.

Ожидается заказ

  • Java In Simple
  • Продвинутая Java

Можно ли получить результат в соответствующем порядке. Или есть ли способ получить количество совпадений для каждого элемента. Например, если поиск («java», «thread», «sleep»), я ожидаю вывод, как показано ниже.

  • Продвинутая Java - 2 совпадения
  • Java в простом - 3 совпадения

Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Это для тех, кто хочет запустить запрос @Alex Blex в Java. Похоже, что шаблон монго не имеет реализации для пересечения. Поэтому я сделал это с помощью Java-клиента mongoDB.

List<String> keywords = Arrays.asList("java", "thread", "sleep");
BasicDBList intersectionList = new BasicDBList();
intersectionList.add("$keywords");
intersectionList.add(keywords);

AggregateIterable<Document> aggregate = new MongoClient("127.0.0.1", 27017).getDatabase("ResourceDB").getCollection("Resource").aggregate(
            Arrays.asList(
                    new BasicDBObject("$addFields",
                            new BasicDBObject("matchedTags",
                                    new BasicDBObject("$size",
                                            new BasicDBObject("$setIntersection", intersectionList)))),
                    new BasicDBObject("$match",
                            new BasicDBObject("matchedTags",
                                    new BasicDBObject("$gt", 0))),
                    new BasicDBObject("$sort",
                            new BasicDBObject("matchedTags", -1))
            )
    );
 MongoCursor<Document> iterator = aggregate.iterator();
 while (iterator.hasNext()){
        Document document = iterator.next();
        System.out.println(document.get("name")+" - "+document.get("matchedTags"));
 }
0 голосов
/ 03 июля 2018

$ in не соответствует 3 или 2 предметам. Он останавливается после первого матча. Необходимо использовать конвейер агрегации для вычисления пересечения ключевых слов и массива из запроса и порядка по размеру результата:

db.collection.aggregate([
    { $addFields: {
        matchedTags: { $size: { 
            $setIntersection: [ "$keywords", [ "java", "thread", "sleep" ] ] 
        } }
    } },
    { $match: { matchedTags: { $gt: 0 } } },
    { $sort: { matchedTags: -1 } }
])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...