Подтвердить что ты не робот

Java - MongoDB + Solr

Я много оглядывался, чтобы посмотреть, как использовать MongoDB в сочетании с Solr, и некоторые вопросы здесь имеют частичные ответы, но ничего конкретного (более похожие на теории). В моем приложении у меня будет много и много документов, хранящихся в MongoDB (возможно, до нескольких сотен миллионов), и я хочу реализовать полнотекстовый поиск по некоторым свойствам этих документов, поэтому, я думаю, Solr - лучший способ сделать это.

Что я хочу знать, как мне настроить/выполнить все, чтобы у него были хорошие показатели? прямо сейчас, вот что я делаю (и я знаю, что это не оптимально):

1- При вставке объекта в MongoDB, я затем добавляю его в Solr

SolrServer server = getServer();
SolrInputDocument document = new SolrInputDocument();
document.addField("id", documentId);
...
server.add(document);
server.commit();

2- При обновлении свойства объекта, поскольку Solr не может обновить только одно поле, сначала я извлекаю объект из MongoDB, затем обновляю индекс Solr со всеми свойствами объекта и новых и делаю что-то вроде

StreamingUpdateSolrServer update = new StreamingUpdateSolrServer(url, 1, 0);
SolrInputDocument document = new SolrInputDocument();
document.addField("id", documentId);
...
update.add(document);
update.commit();

3- При запросе сначала я запрашиваю Solr, а затем при извлечении списка документов SolrDocumentList просматриваю каждый документ и:

  • получить идентификатор документа
  • получить объект от MongoDB с тем же идентификатором, чтобы иметь возможность извлекать из него свойства

4- При удалении, я еще не сделал эту часть и не совсем уверен, как это сделать в Java

У кого-нибудь есть предложения по тому, как это сделать более эффективным образом для каждого из описанных здесь сценариев? как процесс сделать это так, чтобы не потребовалось 1 часа для восстановления индекса при наличии большого количества документов в Solr и добавления одного документа за раз? мои требования здесь состоят в том, что пользователи могут захотеть добавить один документ за раз, много раз, и я бы хотел, чтобы они могли получить его сразу после

4b9b3361

Ответ 1

Ваш подход действительно хорош. Некоторые популярные структуры, такие как Compass, выполняют то, что вы описываете на более низком уровне, чтобы автоматически зеркально отражать изменения индекса, которые были выполнены через структуру ORM (см. http://www.compass-project.org/overview.html).

В дополнение к тому, что вы описали, я бы также регулярно переиндексировал все данные, которые живут в MongoDB, чтобы синхронизировать Solr и Mongo (возможно, не так долго, как вы думаете, в зависимости от числа документа, количество полей, количество токенов на поле и производительность анализаторов: я часто создаю индекс от 5 до 8 миллионов документов (около 20 полей, но текстовые поля короткие) менее чем за 15 минут со сложными анализаторами, просто убедитесь, что буфер RAM не слишком мал и не выполняйте/оптимизируйте, пока не будут добавлены все документы).

Что касается производительности, фиксация стоит дорого, а оптимизация очень дорогостоящая. В зависимости от того, что наиболее важно для вас, вы можете изменить значение mergefactor в Solrconfig.xml(высокие значения улучшают производительность записи, тогда как низкие значения улучшают производительность чтения, 10 - хорошее значение для начала).

Вы, кажется, боитесь времени сборки индекса. Однако, поскольку хранилище индексов Lucene основано на сегментах, пропускная способность записи не должна зависеть слишком сильно от размера индекса (http://lucene.apache.org/java/2_3_2/fileformats.html). Однако время прогрева будет увеличиваться, поэтому вы должны убедиться, что

  • существуют типичные (особенно для сортировки для загрузки полевых кэшей), но не слишком сложные запросы в параметрах firstSearcher и newSearcher в файле конфигурации solrconfig.xml,
  • useColdSearcher установлен в
    • false, чтобы иметь хорошую производительность поиска или
    • true, если вы хотите, чтобы изменения, выполненные с индексом, учитывались быстрее в зависимости от более медленного поиска.

Кроме того, если это приемлемо для вас, если данные становятся доступными для поиска всего за несколько миллисекунд после того, как они были записаны в MongoDB, вы можете использовать функцию commitWithin для UpdateHandler. Таким образом, Solr придется совершать реже.

Для получения дополнительной информации о коэффициентах производительности Solr см. http://wiki.apache.org/solr/SolrPerformanceFactors

Чтобы удалить документы, вы можете либо удалить идентификатор документа (как определено в schema.xml), либо по запросу: http://lucene.apache.org/solr/api/org/apache/solr/client/solrj/SolrServer.html

Ответ 2

  • Вы также можете дождаться большего количества документов и индексирования их только каждые X минут. (Конечно, это очень зависит от вашего приложения и требований)

  • Если ваши документы невелики и вам не нужны все данные (которые хранятся в MongoDB), вы можете поместить в поле Solr только поле, которое вам нужно, сохраняя их, но не индексируя

<field name="nameoyourfield" type="stringOrAnyTypeYouuse" индексируется ="false" хранится ="true"/>