MongoDB,按两个数组之间匹配元素的数量对结果进行排序
Posted
技术标签:
【中文标题】MongoDB,按两个数组之间匹配元素的数量对结果进行排序【英文标题】:MongoDB, sort the results by the number of matching elements between two arrays 【发布时间】:2021-05-16 14:27:48 【问题描述】:在我的项目中,我使用 MongoDB 作为数据库(特别是用于 typescript 的 mongoose 驱动程序,但这不重要),并且我有一系列遵循此架构的帖子:
export const PostSchema = new Schema(
author: type: Types.ObjectId, required: true, ref: 'User' ,
text: type: String, required: true ,
tags: [ type: Types.ObjectId, required: true, ref: 'Tag' ],
location: type: PointSchema, required: true ,
export const PointSchema = new Schema(
type:
type: String,
enum: ['Point'],
required: true,
,
coordinates:
type: [Number],
required: true,
,
locationName:
type: String,
required: true,
,
);
我的问题是是否可以编写一个查询(我认为需要聚合)来返回所有满足条件(例如位置必须在特定距离)的帖子,并按特定的顺序对结果进行排序作为参数传递的标签数组(在我的情况下,数组因用户而异,代表他们的兴趣)。 即选择数组 ["sport", "music", "art"] 为例,我想要一个查询,从数据库中检索所有满足特定条件的帖子(与此问题无关)并排序结果,首先是其标签数组与数组[“sport”,“music”,“art”]共享元素的文档,并且仅在最后没有任何对应关系的文档。 也就是说,像这样:
[
_id: "507f191e810c19729de860ea",
tags: ["sport", "art", "tennis"] // 2 matches
,
_id: "507f191e810c1975de860eg",
tags: ["sport", "food"] // 1 matches
,
_id: "607f191e810c19729de860ea",
tags: ["animals", "art"] // 1 matches
,
_id: "577f191e810c19729de860ea",
tags: ["animals", "zoo"] //0 matches
]
【问题讨论】:
【参考方案1】:如果您的收藏看起来像这样:
[
"author": "John",
"tags": [
ObjectId("60278ce8b370ff29b83226e2"), // Sport
ObjectId("60278ce8b370ff29b83226e8"), // Music
ObjectId("60278ce8b370ff29b83226e5"), // Food
]
,
"author": "Dheemanth",
"tags": [
ObjectId("60278ce8b370ff29b83226e7"), // Tech
ObjectId("60278ce8b370ff29b83226e5"), // Food
ObjectId("60278ce8b370ff29b83226e2") // Sport
]
,
"author": "Niccolo",
"tags": [
ObjectId("60278ce8b370ff29b83226e2"), // Sport
ObjectId("60278ce8b370ff29b83226e8"), // Music
ObjectId("60278ce8b370ff29b83226e3") // Art
]
]
那么这就是解决方案:
db.posts.aggregate([
$lookup:
from: "tags",
let: "tags": "$tags" ,
pipeline: [
$match:
$expr: $in: ["$_id", "$$tags"]
],
as: "tags"
,
$addFields:
"tagCount":
$size:
$filter:
input: "$tags",
as: "tag",
cond: $in: ["$$tag.name", ["sport", "music", "art"]]
,
$sort: tagCount: -1
,
$project:
_id: 1,
tags: "$tags.name"
])
输出:
[
"_id": ObjectId("60278e14b370ff29b83226eb"),
"tags": ["sport", "art", "music"]
,
"_id": ObjectId("60278e14b370ff29b83226e9"),
"tags": ["sport", "food", "music"]
,
"_id": ObjectId("60278e14b370ff29b83226ea"),
"tags": ["sport", "food", "tech"]
]
【讨论】:
完美运行!非常感谢,你拯救了我的一天!至于效率,您认为这是一个可以接受的大规模操作吗?以上是关于MongoDB,按两个数组之间匹配元素的数量对结果进行排序的主要内容,如果未能解决你的问题,请参考以下文章