Как искать ObjectId мангуста в перьях?

У меня есть две услуги по перьям, одна для профилей, а другая для этикеток.

Профиль может иметь массив меток ObjectId из других коллекций.

Теперь у меня есть вход для поиска и пользователь вводит "linux"

Профиль foo должен быть возвращен, поскольку он содержит идентификатор «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"
}

Теперь мне нужно заполнить все метки в ответе профилей, отправить все профили, а затем отфильтровать их вперед с этим значением ввода для поиска.

По мере роста базы данных это будет очень неэффективно, должен существовать лучший способ сделать это, верно?


person ellipticaldoor    schedule 23.06.2017    source источник


Ответы (3)


Вы можете попробовать такой код

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
})
person Ninja    schedule 23.06.2017

Feathers не ограничивает вас ни в чем, что вы можете делать с самим Mongoose, и для того, что вы хотели бы сделать, вы можете использовать Популяция запросов мангуста.

Адаптер feathers-mongoose поддерживает это с помощью параметра запроса $ populate, поэтому запросы

http://localhost:3030/labels?$populate=labels

Следует делать то, что вы ищете.

person Daff    schedule 24.06.2017
comment
Население мангуста можно отключить? Если у меня есть ссылка на пользователя в модели, любой может заполнить и извлечь пароль от пользователя, потому что мангуст игнорирует хуки. - person ellipticaldoor; 26.06.2017
comment
Вы всегда можете delete hook.params.query.$populate и использовать обработчик populate common, который учитывает их. - person Daff; 26.06.2017

В конце концов, я всего два раза обращаюсь к 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 },
            },
        })
    },
},
person ellipticaldoor    schedule 26.06.2017