Ответы пользователя по тегу Sphinx
  • Сортировка по схожести?

    Dzuba
    @Dzuba
    Предложение 1: поскольку поля с фильмами представляют собой биты, то имеет смысл хранить их в виде чисел. Максимальное целое в mysql — 8-байтовый BIGINT. То есть, если всего фильмов тысяча, то потребуется полтора-два десятка таких чисел в каждой записи. Пусть N — количество таких чисел-1, userF0, ..., userFN — эти числа в записи выбранного пользователя. Тогда поиск 10 похожих пользователей в таблице с полями (user_id, f0, ..., fN) будет выглядеть так:
    SELECT user_id FROM таблица
    ORDER BY (BIT_COUNT(f0 & userF0) + ... + BIT_COUNT(fN & userFN)) DESC LIMIT 10;
    Минусы подхода: пробегать при запросе будет все записи, при добавлении новых фильмов нужно вызывать ALTER TABLE. За скорость тоже ручаться не могу.

    Предложение 2: создать 1 таблицу с юзерами и столько таблиц, сколько фильмов, в каждой из которых хранить список id юзеров, выбравших фильм. Тогда поиск похожих юзеров сведется к:
    SELECT tmp.user_id FROM (SELECT user_id FROM таблица1
        UNION ALL
        SELECT user_id FROM таблица2
        UNION ALL
        ...
        UNION ALL
        SELECT user_id FROM таблицаN) AS tmp
    GROUP BY tmp.user_id ORDER BY COUNT(tmp.*) DESC LIMIT 10;
    
    Минусы подхода: большое количество подзапросов, группировка.

    Предложение 3: создать 1 таблицу с юзерами (users) и 1 таблицу с юзеро-фильмами (user_films), т.е. с записями о предпочтениях юзеров следующего вида (user_id, film_id). Тогда для списка фильмов выбранного юзера (film_id0, ..., film_idN) поиск похожих юзеров сведется к:
    SELECT user_id FROM user_films
    WHERE film_id IN (film_id0, ..., film_idN)
    GROUP BY user_id ORDER BY COUNT(*) DESC LIMIT 10;
    
    Минусы подхода: группировка.
    Хотя при индексированном поле film_id может будет и не сильно медленно.
    Ответ написан
    6 комментариев