I have an online game store and code that filters data by tags and genres. But I also want to add filtering by platforms and systems. For example, the system is PC and the platform is Steam. How can I implement this?
Schema
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 controller
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: 'Ошибка получения' })
}
}
I was able to combine genres and tags into one and filter by them, do I really now need to put both the platform and the systems into an array of tags?
2
Answers
Thank you!) This solution works, but I did it a little differently, since I need the search by platforms and systems to be a multi-search, that is, I could filter simultaneously for PC, Xbox, as well as for Steam Origin platforms, etc. So I did this:
Or can I optimize this?
No, you don’t need to put both the platform and the systems into an array of tags. You can filter by platform and system separately.
You can add two more query parameters for platform and system in your API and then use them in your mongoose query. Here’s how you can do it:
In this code, I’ve added two new query parameters platform and system. The platform is a string and system is an array. I’ve used $regex for platform to make it case-insensitive and $in for system to match any system in the array.
Now, you can filter games by platform and system by adding platform and system parameters in your API request like this: /api/games?platform=Steam&system=PC,Mac.
Please replace the file path with your actual file path.