Как агрегировать данные в mongoDB на основе пользовательского ввода? - PullRequest
1 голос
/ 28 мая 2019

Я хотел бы использовать агрегатный каркас в mongoDB для запроса базы данных на основе пользовательского ввода. Я создал приложение, в котором после каждой набранной буквы fetch получает все соответствующие данные. Чем больше букв будет напечатано, тем меньше будет вывод.

Пример

Пользователь вводит букву G , выводится 10 записей JSON. Пользователь вводит Гудвилл , вывод 1 (только одна запись соответствует слову «гудвилл»)

Задача

Мне нужно искать каждую набранную букву или число во всех моих парах значений ключей JSON. Если пользователь что-то вводит, я должен искать header , headerNum , content , contentNum , детали .

В настоящее время я решил эту проблему, но это своего рода обходной путь. Я использую RegExp в mongoDB find () метод для удовлетворения ожидаемых условий. Затем я использую map () , чтобы отфильтровать все результаты, которые соответствуют запросу пользователя.

JSON

        "header": "Intangible assets",
        "headerNum": "10",
        "meta": [
            {
                "meta_id": "1",
                "header": "Intangible assets",
                "headerNum": "10",
                "content": "Random content and goodwill",
                "contentNum": "1080",
                "details": "Some random text with the word goodwill",
                "tags": ["goodwill"]
            }
        ]
    }

Условия

const search = req.query.term.toLowerCase();
const regExp = new RegExp(".*" + search + ".*", "gi");

    let conditions = [{
            "meta.header": regExp
        },
        {
            "meta.tags": regExp
        },
        {
            "meta.content": regExp
        },
        {
            "meta.details": regExp
        }
    ];

    if (typeof parseInt(search) === 'number') {
        conditions.push({"meta.headerNum": regExp}, {"meta.contentNum": regExp});
    }

Создание запроса с поиском и картой

db.getDB()
        .collection(collection)
        .find({
            $or: conditions
        })
        .map(function(record) {
            if (record.header.includes(search) || record.headerNum.includes(search)) {
                return record;
            }

            record.meta = record.meta.filter(function(meta) {
                return meta.tags.find(function(tag) {
                    return tag.toLowerCase().includes(search)
                }) || meta.content.toLowerCase().includes(search) ||
                meta.details.toLowerCase().includes(search) || meta.contentNum.toLowerCase().includes(search)
            });
            return record;
        })
        .sort({headerNum: 1})
        .toArray((err, docs) => {
            if (err) {
                console.log(err);
            } else {
                res.json(docs.filter(function(record) { 
                    return record.meta.length;
                }));
            };
        });

Я хотел бы заменить поиск и карту на агрегатные. Я пытался сделать это с раскруткой , но без удовлетворительного результата. Заранее спасибо!

...