问题
I'm using MERN to develop my project, I have tree category with this structure:
{id: {
type: Number
},
parent_id: {
type: Number
},
name: {
type: String
},
sub: {
type: Boolean
}}
for example :
{
"_id": "5dfa22dbb04cee3960868fd8",
"id": 1,
"name": "Code",
"parent_id": 0,
"sub": true,
"__v": 0
},
{
"_id": "5dfa2358b04cee3960868fda",
"id": 101,
"parent_id": 1,
"name": "JavaScript",
"sub": true,
"__v": 0
},
{
"_id": "5dfa68735dc1004134b259ab",
"id": 1001,
"parent_id": 101,
"name": "React",
"sub": false,
"__v": 0
},
and for each post I have this structure:
{
"_id": "5dfd3b918937d40b98afd3f8",
"user": "5deea38cfc84f42590e01942",
"title": "test",
"description": "description test",
"category":
{
"0": "1",
"1": "101"
},
"phone": "+1",
"country": "USA",
"city": "NY",
"options": {
"transaction_type": ""
},
"date": "2019-12-20T21:22:25.940Z",
"__v": 0
}
for example we have category with id 1 as parent and category with id 101 as child of 1 and child of 101 is 1001 like a tree
now i have a post that category is 1001 so I set category for this post like bottom:
"category": [
{
"0": "1",
"1": "101",
"2": "1001"
}
]
and other post category is 101 so i set like this:
"category": [
{
"0": "1",
"1": "101",
}
]
I want when user select category with id 1 from menu, return all posts have category 1, 101 and 1001 so i use structure like top code to set parent id and child id for post category
Is this method correct or do you suggest a better method?
and in backend with express I using bottom code for find posts in each category but not working what I should to do?
router.get('/category/:category', async (req, res) => {
try {
const posts = await Post.find({'category': {$all: req.params.category}}).sort({ date: -1 });
if (!posts) {
return res.status(404).json({ msg: 'Ads not found' });
}
const resultPosts = posts.slice(req.query.start, req.query.count)
res.json(resultPosts);
} catch (err) {
console.error(err.message);
if (err.kind === 'ObjectId') {
return res.status(404).json({ msg: 'Ads not found' });
}
res.status(500).send('Server Error!');
}});
回答1:
I see that you're using $all operator.
The $all operator selects the documents where the value of a field is an array that contains all the specified elements. To specify an $all expression, use the following prototype: { : { $all: [ , ... ] } }
In your case, you're looking for an object "req.params.category" that has this value:
{
"0": "1",
"1": "101",
"2": "1001"
}
Try this:
// data declaring
const { category } = req.params // destructuring
const posts = await Post.find({ category: category }).sort({ date: -1 });
// It's the same
const posts = await Post.find({ category:
{
"0": "1",
"1": "101",
"2": "1001"
}
}).sort({ date: -1 })
Also, if finally posts equals to cursor , use .next() to converto to the final result.
posts.next()
I hope it works for you. Greetings.
回答2:
I think this structure is not logical so I change my post body to:
{
"_id": "5ea00ded0e94961c0445bd5f",
"category": [
{
"cat_id": 2,
"cat_name": "2"
},
{
"cat_id": 102,
"cat_name": "102"
}
],
"user": "5deeaeeb06f015576080a435",
"title": "test5",
"description": "description5",
"date": "2020-04-22T09:27:09.692Z",
"__v": 0
}
and my schema is:
const PostSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
},
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
category: [
{
cat_id: Number,
cat_name: String
}
],
options: {},
phone: {
type: String,
},
country: {
type: String,
},
city: {
type: String,
},
date: {
type: Date,
default: Date.now
}
});
but the problem it's i can`t find on my category array with this code:
router.get('/category/:category', async (req, res) => {
try {
const posts = await Post.find({category: {cat_name: req.params.category}})
if (!posts) {
return res.status(404).json({ msg: 'Ads not found' });
}
console.log(posts)
res.json(posts);
} catch (err) {
console.error(err.message);
if (err.kind === 'ObjectId') {
return res.status(404).json({ msg: 'Ads not found' });
}
res.status(500).send('Server Error!');
}
});
this return empty array [], I don't know why!
when I get all posts in console log my result is:
{
category: [ [Object], [Object] ],
_id: 5ea00ded0e94961c0445bd5f,
user: 5deeaeeb06f015576080a435,
title: 'test5',
description: 'description5',
date: 2020-04-22T09:27:09.692Z,
__v: 0
}
回答3:
The problem was solved this way: link
But I'm still happy to share your experiences about content categorization
so my final get posts by category is:
router.get('/category/:category', async (req, res) => {
try {
const posts = await Post.find({category: {$elemMatch: {cat_name: 'req.params.category'}}})
if (!posts) {
return res.status(404).json({ msg: 'Ads not found' });
}
console.log(posts)
res.json(posts);
} catch (err) {
console.error(err.message);
if (err.kind === 'ObjectId') {
return res.status(404).json({ msg: 'Ads not found' });
}
res.status(500).send('Server Error!');
}
});
来源:https://stackoverflow.com/questions/61352430/what-structure-for-create-tree-category-and-set-in-posts-is-better-and-find-pos