我正在创建搜索应用程序,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”,“线程”,“睡眠”),则期望输出如下。
任何帮助表示赞赏。
答案 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"));
}