Я хотел бы использовать агрегатный каркас в 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;
}));
};
});
Я хотел бы заменить поиск и карту на агрегатные. Я пытался сделать это с раскруткой , но без удовлетворительного результата. Заранее спасибо!