我有一个在线游戏商店和代码,可以通过标签和流派过滤数据。但我还想添加平台和系统过滤。例如,系统是PC,平台是Steam。我如何实现这一点?
架构
const mongoose = require("mongoose");
const slug = require('mongoose-slug-updater');
const options = {
separator: "-",
lang: "en",
truncate: 120
}
mongoose.plugin(slug, options);
const GamesSchema = new mongoose.Schema({
title: String,
slug: { type: String, slug: ["title"], slugPaddingSize: 2, unique: true },
last_url: String,
description: String,
preview: {
src: String,
alt: String
},
stock_price: String,
discount: Number,
total_price: String,
system: Array,
platform: String,
info: {
Genre: Array
},
tags: Array,
config: Object,
images: Array,
keys: Array,
content: String
})
module.exports = mongoose.model("Games", GamesSchema);
字符串
API控制器
async get(req, res) {
try {
const page = parseInt(req.query.page) - 1 || 0;
const limit = parseInt(req.query.limit) || 5;
const search = req.query.search || '';
let sort = req.query.sort || "top";
let tags = req.query.tags || 'all';
const tagsOpt = [];
Games.find().then(async games => {
games.forEach(game => {
game.tags.forEach(tag => {
if (!tagsOpt.includes(tag)) {
tagsOpt.push(tag)
}
})
})
tags === 'all' ? (tags = [...tagsOpt]) : (tags = req.query.tags.split(','));
req.query.sort ? (sort = req.query.sort.split(',')) : (sort = [sort]);
let sortBy = {};
if (sort[1]) {
sortBy[sort[0] = sort[1]];
} else {
sortBy[sort[0] = "top"]
}
const gamesData = await Games.find({ title: { $regex: search, $options: 'i' } })
.where('tags')
.in([...tags])
.sort(sortBy)
.skip(page * limit)
.limit(limit);
const total = await Games.countDocuments({
tags: { $in: [...tags] },
title: { $regex: search, $options: 'i' },
});
const response = {
error: false,
total,
page: page + 1,
limit,
tags: tagsOpt,
gamesData
};
res.status(200).json(response);
})
} catch (error) {
console.log(error);
res.status(400).json({ message: 'Ошибка получения' })
}
}
型
我能够将合并类型和标签组合成一个并通过它们进行过滤,我现在真的需要将平台和系统都放入一个标签数组中吗?
3条答案
按热度按时间13z8s7eq1#
不需要,您不需要将平台和系统都放入标签数组中。您可以分别按平台和系统进行筛选。
您可以在API中为平台和系统添加两个查询参数,然后在mongoose查询中使用它们。具体操作如下:
字符串
在这段代码中,我添加了两个新的查询参数platform和system。platform是一个字符串,system是一个数组。我为platform使用了$regex,使其不区分大小写,为system使用了$in,以匹配数组中的任何系统。
现在,您可以通过在API请求中添加平台和系统参数来按平台和系统过滤游戏,如下所示:/API/games?platform=Steam&system=PC,Mac。
请将文件路径替换为实际文件路径。
cngwdvgl2#
谢谢你,谢谢)这个解决方案是有效的,但我做得有点不同,因为我需要按平台和系统进行多搜索,也就是说,我可以同时过滤PC,Xbox以及Steam Origin平台等。
字符串
我可以优化它吗?
cetgtptt3#
你的代码执行了很多可以优化的操作。下面是一些建议:
使用MongoDB的聚合框架:聚合框架是一个强大的工具,允许您直接在数据库中对数据执行复杂的转换和计算。这比检索数据并在应用程序中处理它要快得多。避免不必要的数据库调用:您的代码当前调用了Games.find()两次,一次是获取标签、平台、系统和语言的选项,一次用于获取实际的游戏数据。您可以使用聚合框架将其减少为单个调用。使用投影来限制数据库返回的字段:如果您只需要文档中的某些字段,可以使用投影来限制返回的字段。这可以减少需要从数据库传输到应用程序,可以提高性能。
下面是一个如何实现这些建议的示例:
字符串
这段代码使用aggregation框架直接在数据库中执行所有的过滤、排序和分页。它还使用投影来限制返回的字段,尽管你需要在$project阶段填写你需要的字段。
请注意,此代码假设如果为标签、平台、系统或语言传递了“all”,则意味着该字段可以接受任何值。如果“all”应被视为特定值,则需要相应地调整代码。
此外,这段代码没有在响应中包含标签,平台,系统和语言的选项。如果你仍然需要这些选项,你可以考虑缓存它们,以避免每次都需要计算它们。