У меня есть две функции перьев, одна для профилей, а другая для ярлыков.
Профиль может иметь массив меток ObjectId из других коллекций.
Теперь у меня есть вход для поиска, а пользователь типа "linux"
Профиль foo должен быть возвращен, поскольку он содержит идентификатор "594ceeff6905e622425f523b" в массиве меток.
Этот вид поискового запроса через ObjectId между объектами возможен через перья?
{
name: { type: String, trim: true, required: true },
labels: [{ type: ObjectId, ref: 'Labels' }],
}
получить http://localhost: 3030/profiles
{
"name" : "foo",
"labels" : [
"594ceeff6905e622425f523b",
"594ceeff6905e622425f523c",
"594ceeff6905e622425f523d"
],
}
{
"name" : "bar",
"labels" : [
"594ceeff6905e622425f523e",
"594ceeff6905e622425f523d"
],
}
{
name: { type: String, trim: true, unique: true, required: true },
}
получить http://localhost: 3030/labels
{
"_id": "594ceeff6905e622425f523b",
"name": "linux"
},
{
"_id": "594ceeff6905e622425f523c",
"name": "systemd"
},
{
"_id": "594ceeff6905e622425f523d",
"name": "mongodb"
},
{
"_id": "594ceeff6905e622425f523e",
"name": "javascript"
}
Теперь я должен заполнить все метки в ответе профилей, отправить все профили и затем фильтровать их по фронту с этим значением ввода для поиска.
По мере роста базы данных это будет очень неэффективно, у него должен быть лучший способ сделать это правильно?
Перья не ограничивают вас тем, что вы можете сделать с самим Mongoose, и за то, что вы хотели бы сделать, вы можете использовать популяцию запросов Mongoose.
Адаптер feathers-mongoose
поддерживает это через параметр запроса $ populate, поэтому запрос
Http://Localhost: 3030/этикетки $ заселить = метки
Должен делать то, что вы ищете.
Вы можете попробовать код, подобный этому
Profile.find({}).populate({
path: 'labels',
match: {
name: {
$regex: new RegExp(searchText, 'i');
//searchText: passed from the front end.
}
}
}).then(function(profiles){
var filteredProfiles = profiles.forEach(function(profile){
return profile.labels; //will be null for items don't match the
//searching regex.
//resolve the filtered profiles to the front end.
})
},function(error){
//Error handling
})
Я в конце концов, я просто два призыва к api вот так:
computed: {
...mapState('profiles', { profiles: 'keyedById' }),
...mapState('labels', { labels: 'keyedById' }),
},
methods: {
...mapActions('profiles', { findProfiles: 'find' }),
async fetch() {
const labels = this.labels
const search = this.search_input.toLowerCase()
// Generates an array of matched labels per profile
const labels_id = Object.keys(labels).filter(label => {
const name = labels[label].name.toLowerCase()
return name.includes(search)
})
// Searches profiles by name or labels
this.findProfiles({
query: {
$or: [
{
name: { $regex: search, $options: 'igm' },
},
{ labels: { $in: labels_id } },
],
$populate: ['user'],
$sort: { updatedAt: -1 },
},
})
},
},
delete hook.params.query.$populate
и использовать общий хукdelete hook.params.query.$populate
который учитывает хуки.