Какая структура для создания категории дерева и набора в постах лучше? и найти сообщения по выбранной категории в MERN - PullRequest
0 голосов
/ 21 апреля 2020

Я использую MERN для разработки своего проекта, у меня есть древовидная категория с такой структурой:

{id: {
    type: Number
},
parent_id: {
    type: Number
},
name: {
    type: String
},
sub: {
    type: Boolean
}}

например:

 {
    "_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
},

и для каждого поста у меня есть эта структура :

    {
    "_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
}

например, у нас есть категория с идентификатором 1 в качестве родителя и категория с идентификатором 101 в качестве дочернего элемента 1 и дочернего элемента 101 в 1001 как дерево

теперь у меня есть сообщение, которое категория - 1001, поэтому я устанавливаю категорию для этого сообщения, например, снизу:

        "category": [
        {
            "0": "1",
            "1": "101",
            "2": "1001"
        }
    ]

, а другая категория сообщения - 101, поэтому я устанавливаю так:

            "category": [
        {
            "0": "1",
            "1": "101",
        }
    ]

Я хочу, когда пользователь выбирает категорию с помощью Идентификатор 1 из меню, возврат всех сообщений с категориями 1, 101 и 1001, поэтому я использую структуру, например верхний код, для установки родительского идентификатора и дочернего идентификатора для категории сообщений

Это правильный метод или вы предлагаете лучший метод?

и в бэкэнде с express Я использую нижний код для поиска сообщений в каждой категории, но не работаю, что я должен делать?

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!');
}});

Ответы [ 3 ]

0 голосов
/ 22 апреля 2020

Я думаю, что эта структура не логична, поэтому я изменяю свое тело сообщения на:

{
    "_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
}

и моя схема:

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
}

});

но проблема в том, что я не могу найти в своем массиве категорий следующий код:

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!');
}

});

этот возвращаемый пустой массив [], я не знаю почему!

когда я получаю все сообщения в журнале консоли, мой результат:

{ category: [ [Object], [Object] ], _id: 5ea00ded0e94961c0445bd5f, user: 5deeaeeb06f015576080a435, title: 'test5', description: 'description5', date: 2020-04-22T09:27:09.692Z, __v: 0 }

0 голосов
/ 22 апреля 2020

Проблема была решена следующим образом: ссылка

Но я все еще рад поделиться с вами вашим опытом по категоризации контента

, поэтому мой последний пост по категориям: :

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!');
}

});

0 голосов
/ 22 апреля 2020

Я вижу, что вы используете оператор $ all.

Оператор $ all выбирает документы, где значение поля представляет собой массив, содержащий все указанные элементы. Чтобы указать выражение $ all, используйте следующий прототип: {: {$ all: [, ...]}}

В вашем случае вы ищете объект "req.params .category ", которая имеет это значение:

{
 "0": "1",
 "1": "101",
 "2": "1001"
}

Попробуйте это:

// 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 })

Кроме того, если, наконец, сообщения равны курсору, используйте .next () для преобразования в конечный результат.

posts.next() 

Я надеюсь, что это работает для вас. Привет.

...