MongoDB通过$ in命令获取匹配数

时间:2018-07-03 15:46:41

标签: java mongodb spring-mongodb

定义

我正在创建搜索应用程序,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"
   ]
}

这包含书名和每本书的最常用单词(以关键字排列)。我正在使用带有mongo模板的spring框架。如果我运行以下代码,

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简单”匹配3个单词,而“高级Java”仅匹配2个单词。因此,最相关的书的可能性应该是“ Java In Simple”,并且应该放在第一位。

期望订单

  • 简单的Java
  • 高级Java

是否有可能获得匹配顺序的结果。或者有什么方法可以获取每个项目的匹配数。例如,如果正在搜索(“ java”,“线程”,“睡眠”),则期望输出如下。

  • 高级Java-2个匹配项
  • 简单的Java-3个匹配项

任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:2)

$ in与3或2个项目不匹配。比赛结束后停止。您需要使用聚合管道来根据查询的大小和结果的大小来计算关键字intersection和查询的数组:

s

答案 1 :(得分:1)

这适用于希望在Java中运行@Alex Blex的查询的人。看起来mongo模板没有交叉的实现。因此,我已经使用mongoDB java客户端完成了此操作。

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