如何在羽毛中搜索mongoose ObjectId?

时间:2017-06-23 11:58:09

标签: javascript mongodb mongoose feathersjs

我有两种羽毛服务,一种用于配置文件,另一种用于标签。

配置文件可以包含来自其他集合的ObjectId标签数组。

现在我有一个搜索输入和一个用户输入“linux”

应该返回配置文件foo,因为它在标签数组中包含id“594ceeff6905e622425f523b”。

通过羽毛可以通过对象之间的ObjectId进行这种搜索查询吗?

配置文件

猫鼬模型

{
    name: { type: String, trim: true, required: true },
    labels: [{ type: ObjectId, ref: 'Labels' }],
}

Feathers api得到对个人资料的回应

获取http://localhost:3030/profiles

{
    "name" : "foo",
    "labels" : [
        "594ceeff6905e622425f523b",
        "594ceeff6905e622425f523c",
        "594ceeff6905e622425f523d"
    ],
}

{
    "name" : "bar",
    "labels" : [
        "594ceeff6905e622425f523e",
        "594ceeff6905e622425f523d"
    ],
}

标签

猫鼬模型

{
    name: { type: String, trim: true, unique: true, required: true },
}

Feathers api得到对标签的响应

获取http://localhost:3030/labels

{
    "_id": "594ceeff6905e622425f523b",
    "name": "linux"
},
{
    "_id": "594ceeff6905e622425f523c",
    "name": "systemd"
},
{
    "_id": "594ceeff6905e622425f523d",
    "name": "mongodb"
},
{
    "_id": "594ceeff6905e622425f523e",
    "name": "javascript"
}

现在我必须在配置文件响应中填充所有标签,发送所有配置文件,然后在前面使用输入的值进行搜索。

随着数据库的增长,这将是非常低效的,它必须存在一种更好的方法来做到这一点吗?

3 个答案:

答案 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 },
            },
        })
    },
},