我有两种羽毛服务,一种用于配置文件,另一种用于标签。
配置文件可以包含来自其他集合的ObjectId标签数组。
现在我有一个搜索输入和一个用户输入“linux”
应该返回配置文件foo,因为它在标签数组中包含id“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"
}
现在我必须在配置文件响应中填充所有标签,发送所有配置文件,然后在前面使用输入的值进行搜索。
随着数据库的增长,这将是非常低效的,它必须存在一种更好的方法来做到这一点吗?
答案 0 :(得分:2)
您可以尝试这样的代码
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
})
答案 1 :(得分:2)
Feathers不会限制您使用Mongoose本身可以做的任何事情,并且您想要做的事情可以使用Mongoose query population。
feathers-mongoose
适配器通过$populate query parameter查询
http://localhost:3030/labels?$populate=labels
应该做你想要的。
答案 2 :(得分:0)
我结束时我只是两次打电话给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 },
},
})
},
},