定义
我正在创建搜索应用程序,mongo db用于存储搜索信息。这是集合"Resource“的示例数据集。
{
_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);
它的结果是“高级Java”和“简单的Java”,并且它是ok的。
问题
但在我的情况下,我需要它们按顺序排列。因为"Java In Simple“匹配3个单词,而"Advanced Java”只匹配2个单词。因此,最相关的书的可能性应该是"Java In Simple“,并且应该放在第一位。
期望订单
Simple
中的
有没有可能得到匹配顺序的结果?或者有没有办法获得每一项的匹配数。例如,如果是search For ("java","thread","sleep"),我希望得到如下输出。
感谢您的帮助。
发布于 2018-07-03 23:59:15
$in与3或2个项目不匹配。它在第一次匹配后停止。您需要使用聚合管道来计算来自查询的关键字和数组的intersection,并按结果的大小排序:
db.collection.aggregate([
{ $addFields: {
matchedTags: { $size: {
$setIntersection: [ "$keywords", [ "java", "thread", "sleep" ] ]
} }
} },
{ $match: { matchedTags: { $gt: 0 } } },
{ $sort: { matchedTags: -1 } }
])
发布于 2018-07-04 04:06:59
这是为那些想要在java中运行@Alex Blex查询的人准备的。看起来mongo模板没有交集的实现。所以我使用mongoDB java client完成了这项工作。
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"));
}
https://stackoverflow.com/questions/51158564
复制相似问题