MongoDB 通过 $in 命令获取匹配数
MongoDB get number of matches by $in command
定义
我正在创建搜索应用程序,mongo 数据库用于存储搜索信息。这是集合 "Resource".
的示例数据集
{
_id:"5b3b84e02360a26f9a9ae96e",
name:"Advanced Java",
keywords:[
"java", "thread", "state", "public", "void"
]
},
{
_id:"5b3b84e02360a26f9a9ae96f",
name:"Java In Simple",
keywords:[
"java", "runnable", "thread", "sleep", "array"
]
}
这包含每本书的名称和最常用的单词(在关键字数组中)。我正在使用 spring 框架和 mongo 模板。如果我 运行 下面的代码,
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 简单
- 高级Java
是否可以按匹配的顺序得到结果。或者有什么方法可以获取每个项目的匹配项数。例如,如果搜索 ("java"、"thread"、"sleep"),我希望输出如下所示。
- 高级 Java - 2 场比赛
- Java 简单 - 3 场比赛
感谢任何帮助。
$in 不匹配 3 或 2 项。它在第一场比赛后停止。您需要使用聚合管道从查询中计算 intersection 关键字和数组,并按结果大小排序:
db.collection.aggregate([
{ $addFields: {
matchedTags: { $size: {
$setIntersection: [ "$keywords", [ "java", "thread", "sleep" ] ]
} }
} },
{ $match: { matchedTags: { $gt: 0 } } },
{ $sort: { matchedTags: -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"));
}
定义
我正在创建搜索应用程序,mongo 数据库用于存储搜索信息。这是集合 "Resource".
的示例数据集{
_id:"5b3b84e02360a26f9a9ae96e",
name:"Advanced Java",
keywords:[
"java", "thread", "state", "public", "void"
]
},
{
_id:"5b3b84e02360a26f9a9ae96f",
name:"Java In Simple",
keywords:[
"java", "runnable", "thread", "sleep", "array"
]
}
这包含每本书的名称和最常用的单词(在关键字数组中)。我正在使用 spring 框架和 mongo 模板。如果我 运行 下面的代码,
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 简单
- 高级Java
是否可以按匹配的顺序得到结果。或者有什么方法可以获取每个项目的匹配项数。例如,如果搜索 ("java"、"thread"、"sleep"),我希望输出如下所示。
- 高级 Java - 2 场比赛
- Java 简单 - 3 场比赛
感谢任何帮助。
$in 不匹配 3 或 2 项。它在第一场比赛后停止。您需要使用聚合管道从查询中计算 intersection 关键字和数组,并按结果大小排序:
db.collection.aggregate([
{ $addFields: {
matchedTags: { $size: {
$setIntersection: [ "$keywords", [ "java", "thread", "sleep" ] ]
} }
} },
{ $match: { matchedTags: { $gt: 0 } } },
{ $sort: { matchedTags: -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"));
}