市场架构:
const MarketSchema = new mongoose.schema({
marketName: String,
// ... rest of the fields
});
主持人架构:
const ModeratorSchema = new mongoose.Schema({
name: String,
username: String,
// ... rest of the fields
});
现在是我正在尝试处理的文档
主持人到市场映射架构:
const ModeratorToMarketMappingSchema = new mongoose.Schema({
moderatorId: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
marketId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Market",
},
// ... rest of the fields
});
我想根据市场的
marketName
或使用 ModeratorToMarketMapping 文档根据主持人的 name or username
过滤数据。
我希望结果类似于以下查询将产生的结果
如果按市场搜索
SELECT *
FROM Users AS u
JOIN ModeratorToMarketMapping AS map ON u.id = map.moderatorId
JOIN Market AS m ON map.marketId = m.id
WHERE m.marketName LIKE '%${FILTER_VALUE}%'
如果按姓名/用户名搜索
SELECT *
FROM Users AS u
JOIN ModeratorToMarketMapping AS map ON u.id = map.moderatorId
JOIN Market AS m ON map.marketId = m.id
WHERE u.name LIKE '%${FILTER_VALUE}%' OR u.username LIKE '%${FILTER_VALUE}%'
我想到了两种方法
在此解决方案中,如果我想按市场过滤,那么我首先从
Market Collection
搜索“市场”,然后从 id's of moderator
获取 Mapping schema
,然后相应地填充数据,类似地,如果我想按名称或用户名,然后我首先获取 moderators
,然后从 id's of markets
获取 Mapping schema
,然后填充数据
现在很明显,这是一个
not
的好方法,但当要搜索的数据增长时肯定会失败。
所以我搜索了第二种方法,最终得到了这个,但这不起作用,因为我希望它起作用。
其代码如下
const { criteriaKey, filterValue } = req.query;
let query = {};
if (criteriaKey && filterValue) {
const regex = new RegExp(filterValue, "i");
if (criteriaKey === "market") {
query = { "market.marketName": { $regex: regex } };
} else if (criteriaKey === "name") {
query = {
$or: [
{ "moderator.name": { $regex: regex } },
{ "moderator.username": { $regex: regex } },
],
};
}
}
const moderators = await ModeratorMarketMapping.aggregate([
{
$match: query,
},
{
$lookup: {
from: "markets",
localField: "marketId",
foreignField: "_id",
as: "market",
},
},
{
$lookup: {
from: "users",
localField: "moderatorId",
foreignField: "_id",
as: "moderator",
},
},
{
$unwind: { path: "$market", preserveNullAndEmptyArrays: true },
},
{
$unwind: { path: "$moderator", preserveNullAndEmptyArrays: true },
},
]);
如何使有关代码工作,或者除了切换到 RDBMS 之外还有其他更好的方法吗
您设计模式的方式确实需要关系数据,并且您已经通过聚合来解决它。如果您可以使其工作,那么这可能是适合您当前模式的正确方法,但 mongodb 是为灵活性而设计的。在您的情况下,非规范化可能是最佳方法。
您可以像这样存储彼此的引用:
市场架构:
const MarketSchema = new mongoose.schema({
marketName: String,
moderatorId: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
// ... rest of the fields
});
主持人/用户架构:
const UserSchema = new mongoose.Schema({
name: String,
username: String,
marketId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Market",
},
// ... rest of the fields
});
然后,当您的查询出现时,决定用于查询的模型和
populate
参考,如下所示:
const { criteriaKey, filterValue } = req.query;
if (criteriaKey && filterValue) {
if (criteriaKey === "market") {
const docs = await Market.find({
marketName: {
$regex: filterValue, $options: 'i'
}
}).populate('moderatorId');
} else if (criteriaKey === "name"){
const docs = await User.find({
$or: [
{ name: { $regex: filterValue, $options: 'i' } },
{ username: { $regex: filterValue, $options: 'i' } },
]
}).populate('marketId');
}
}