在检查匹配项的同时使用聚合 Mongoose 查询的结果(Mongoose/Express)
Posted
技术标签:
【中文标题】在检查匹配项的同时使用聚合 Mongoose 查询的结果(Mongoose/Express)【英文标题】:Use Results From Aggregate Mongoose Queries While Also Checking for Matches (Mongoose/Express) 【发布时间】:2021-09-10 14:10:04 【问题描述】:我有一个用户和帖子集合:
const posts = [
post_id: "123abc", author_id: "cba321", body: "postdatastuff",
post_id: "456def", author_id: "fed654", body: "postdatastuff",
post_id: "789hij", author_id: "fed654", body: "postdatastuff",
post_id: "101klm", author_id: "mlk101", body: "postdatastuff",
]
const users = [
user_id: "cba321", liked_posts: ["123abc", "456def"],
user_id: "fed654", liked_posts: ["789hij", "123abc"],
user_id: "jih987", liked_posts: ["456def", "123abc", "789hij"],
]
如果我以用户“cba321”的身份登录,并且我想返回用户“fed654”的所有帖子,同时还要检查我是否喜欢他们的每个帖子,我将如何编写 mongoose 聚合查询实现这一目标?
这个聚合函数会返回:
const posts = [
post_id: "456def", author_id: "fed654", body: "postdatastuff", liked: true,
post_id: "789hij", author_id: "fed654", body: "postdatastuff", liked: false,
];
目前,我正在写这个没有猫鼬聚合。我的解决方案不仅不起作用,而且效率不高,因为它必须将值返回到服务器并在 2 个单独的进程中处理它们,我希望它是一个 100% 的 mongoose 本机聚合函数。
这是我的尝试:
router.post("path", async (req, res) =>
const reqUser = await User.findOne( _id: req.body.u_id ).lean(); //gets requesting users user information
const user = await User.findOne( uName: req.body.uName ).lean(); //gets the url's path userName user information.
const posts = await Post.find( a_id: user._id ).lean(); //gets all the posts from the previously searched user
const resData = posts.map((p) =>
return
...p,
author_name: user.name, //combines the users name as the author name with each post
author_uName: user.uName,
liked: reqUser.likes.indexOf(p._id), //checks to see if the requesting user has liked the post
;
);
res.status(200).json(resData);
);
这个函数返回类似:
]
_id: 123abc,
body: 'testbodytext',
author_id: 'cba321',
a_name: 'test',
a_uName: 'test',
liked: -1
]
当您查看显示用户发布的其他用户页面/个人资料以及您是否喜欢他们时,此查询聚合复制了 youtube 或 twitter 的功能。
基本上,此函数从用户集合中获取用户/作者的单个 _id,并使用它在帖子集合中搜索任何匹配的 author_id。然后它将返回所有匹配的帖子,同时检查请求用户是否喜欢每个帖子。
我正在寻找不基于 javascript、promise、异步或瀑布方法的答案。
谢谢!
【问题讨论】:
【参考方案1】:如果我以用户“cba321”的身份登录,并且我想退回所有 发布用户“fed654”,同时检查我是否喜欢每个 他们的帖子,...
您查询 users
集合并提供两个输入变量 - 登录用户和您喜欢的帖子的作者/用户 - 以获得所需的结果。查询在mongo
shell 中运行,返回以下结果:
"post_id" : "456def",
"author_id" : "fed654",
"body" : "postdatastuff",
"liked" : true
聚合查询:
db.users.aggregate([
$match: user_id: "cba321" // <-- signed in user
,
$unwind: "$liked_posts"
,
$lookup:
from: "posts",
let: likedPost: "$liked_posts" ,
pipeline: [
$match:
$expr:
$and: [
$eq: [ "$post_id", "$$likedPost" ] ,
$eq: [ "fed654", "$author_id" ] // <-- posts for a specified user/author
]
],
as: "matched_posts",
,
$match:
$expr: $gt: [ $size: "$matched_posts" , 0 ]
,
$unwind: "$matched_posts"
,
$replaceWith: "$matched_posts"
,
$addFields:
_id: "$$REMOVE",
liked: true
,
])
【讨论】:
以上是关于在检查匹配项的同时使用聚合 Mongoose 查询的结果(Mongoose/Express)的主要内容,如果未能解决你的问题,请参考以下文章
mongodb 在节点中使用 mongoose 想要在查询中使用 or 和