What structure for create tree category and set in posts is better? and find posts by selected category in MERN

∥☆過路亽.° 提交于 2020-04-30 06:37:07

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!