Лучший способ отфильтровать поля, хранящиеся в удаленной базе данных в Solr / Lucene? - PullRequest
8 голосов
/ 13 апреля 2011

У меня есть индекс около 100 тыс. Документов, представляющих сущность фильма.

Пользователи могут помещать фильмы в различные списки (например, избранное и т. Д.)

Эти списки хранятся в базе данных mysql.и не индексируются в solr.

Я мог бы хранить идентификаторы пользователей в многозначных полях, представляющих список, но это очень плохо, потому что поля получались бы очень, очень длинными и индексация тоже была бы проблематичной.

Так что в настоящее время я делаю следующее (псевдокод):

$favorites = SELECT document_id FROM favorites WHERE user_id = $user_id
$documents = 'http://solr.com:8393/select/?q=XYZ&fq=document_id:('.join(' OR ',$favorites);

это работает отлично и быстро, но количество элементов в запросах фильтра ограничено 1024 (я пробовал это).также фильтр запросов сложить.поэтому, если у меня есть один фильтр-запрос с 500 значениями для фильтрации, у меня могут быть другие значения для 524 фильтров в другом поле.

Пока все нормально, потому что я ограничил количество записей в списке 1024, и это довольно много, ноЯ думаю, что этот подход очень неуклюжий и приводит к большим накладным расходам.

Разве нет лучшего решения?Как написать модуль Solr, который напрямую подключается к базе данных или что-то?Я хотел бы сделать это в php.

Если нет другого пути, могу ли я как-нибудь поднять предел 1024?потому что это работает очень быстро сейчас!Я думаю, что с хорошим оборудованием больше проблем не будет.

Редактировать: как указано в комментариях, я публикую свою исходную схему и рабочий пример запроса.

<field name="film_id" type="int" indexed="true" stored="true" required="true"/> 
<field name="imdb_id" type="int" indexed="true" stored="true" /> 
<field name="parent_id" type="int" indexed="true" stored="true"/> 
<field name="malus" type="int" indexed="true" stored="true"/> 
<field name="type" type="int" indexed="true" stored="true"/> 
<field name="year" type="int" indexed="true" stored="true" termVectors="true"/> 
<field name="locale_title" type="string" indexed="false" stored="true"/> 
<field name="aka_title" type="filmtitle" indexed="true" stored="true" multiValued="true" omitNorms="true" termVectors="true" /> 
<field name="sort_title" type="string" indexed="true" stored="true"/> 
<field name="director" type="person" indexed="true" stored="true" multiValued="true" omitNorms="true"/> 
<field name="director_phonetic" type="person_phonetic" multiValued="true" omitNorms="true"/> 
<field name="actor" type="person" indexed="true" stored="true" multiValued="true" omitNorms="true"/> 
<field name="actor_phonetic" type="person_phonetic" multiValued="true" omitNorms="true"/> 
<field name="country" type="string" indexed="true" stored="true" multiValued="true"/> 
<field name="description" type="text" indexed="true" stored="true" /> 
<field name="genre" type="genre" indexed="true" stored="true" multiValued="true" termVectors="true"/> 
<field name="url" type="string" indexed="true" stored="true" multiValued="false"/> 
<field name="image_url" type="string" indexed="false" stored="true" multiValued="false"/>
<field name="rating" type="int" indexed="true" stored="true" required="false" default="50"/>
<field name="affiliate" type="string" indexed="true" stored="true" multiValued="true"/>
<field name="product_type" type="string" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="product_*" type="string" indexed="true" stored="true" multiValued="true"/>
<field name="blockbuster" type="boolean" indexed="true" stored="true" /> 
<copyField source="film_id" dest="id"/>
<field name="director_id" type="string" indexed="true" stored="true" multiValued="true" termVectors="true"/>
<field name="actor_id" type="string" indexed="true" stored="true" multiValued="true" termVectors="true"/>

вот моиВ дополнение к стандартному schema.xml

пример результатов поиска можно просмотреть здесь .

пример запроса:

http://my-server.com:8983/solr/select/?
q=description:nazis
&fq=product_bluray:amazon
&fq=film_id:(1185616 1054606 88763 361748 78748)

здесьпользователь будет искать фильмы, которые:

  • доступны на Amazon в виде синего цвета
  • , которые имеют термин "нацисты" в описании
  • И которые включеныего список избранного

список включает фильмы (документы) с идентификаторами 1185616 1054606 88763 361748 78748 и хранится в базе данных mysql.

ps:Не знаю, правильно ли я сформулировал вопрос, надеюсь, это понятно.Если нет, пожалуйста, не стесняйтесь редактировать!

1 Ответ

3 голосов
/ 18 апреля 2011

Первый шаг - убедиться, что вы действительно хотите использовать Solr.Если посмотреть на вашу схему, то там очень много всего, что восприимчиво к нормальной СУБД с базовой индексацией текста.Потратьте полчаса и посмотрите на postgresql, если только вы не определили, что обычная старая добросовестная СУБД с некоторыми дополнительными прибамбасами просто не подойдет вам.

В этой проблеме есть большой интересСообщество Solr, но реального решения не существует.

Очевидный подход состоит в том, чтобы переиндексировать «избранный» документ каждый раз, когда кто-то добавляет его со своим именем пользователя в многозначное поле.Конечно, это просто умопомрачительно, но это не значит, что оно не будет работать, в зависимости от того, как часто один из ваших пользователей связывается со своим списком избранных.Если ваши документы имеют небольшой размер (я предполагаю, что они всего лишь несколько K), и у вас может быть достаточно оборудования для хранения всего индекса в памяти (вероятно, поскольку у вас есть только 100K документов), это может быть подход, чтобы рассмотреть,Вы можете проверить это, построив индекс размера, который вы можете фактически вписать в доступную память и реализовать стратегию.Посмотрим, достаточно ли это быстро.

Вы также можете «пакетировать» эти операции, если люди не добавляют газиллион фаворитов за один раз, например:

  • День 1: я добавляю десять элементов кмои любимые.Вы помещаете их идентификаторы в базу данных и используете этот список идентификаторов для фильтрации моих запросов.
  • Ночь 1: вы обновляете все документы, которые были добавлены кем-либо в течение дня, добавляя мое имя пользователя в «favouritedBy»многозначное поле.Удалите мой список избранного из БД, поскольку теперь он представлен в самом индексе Solr.
  • День 2: я добавляю еще три элемента в избранное.Вы фильтруете по обоим избранным: myusername и id: (newID1 ИЛИ newID2 или newID3).

Это может работать для вас, если люди добавляют разумное количество избранных в день, а у вас малодвижения ночью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...