Частичные обновления в документах Solr / Lucene - PullRequest
3 голосов
/ 04 февраля 2020

Недавно мы начали изучать частичные обновления индекса Solr.

API для полных и частичных обновлений выглядит примерно так. Вместо

doc.addField("location", "UK")
solrClient.add(doc)

вы должны написать

doc.addField("location", map("set", "Germany"))
solrClient.add(doc)

Что я ожидал: solr обновит инвертированный индекс для поля "location"

Что на самом деле происходит:

  • solr загружает сохраненные поля для документа
  • применяет данные обновления для документа
  • удаляет документ с идентификатором
  • записывает документ в индекс

В результате все несохраненные поля теряются.

Я нашел несколько старых обсуждений в списках рассылки, люди говорят, что это ожидаемое поведение, вам нужно сохранить все поля и т. Д. , Мы не хотим, чтобы все поля были сохранены. Свойство «Сохранено» было разработано для полей, которые должны быть возвращены в ответ от Solr вызывающей стороне. Нам нужна только небольшая мета-информация в ответах, поэтому все сохраненные поля выглядят как излишние.

Вопрос в том, почему solr / lucene выполняет все эти шаги для выполнения частичного обновления? В моем понимании, каждое поле имеет свой собственный инвертированный индекс, расположенный в своем собственном файле, поэтому должна быть возможность обновлять поля независимо. Судя по тому, что на самом деле происходит, solr / lucene не может обновить индекс для одного поля, и я не могу найти причину для этого.

Обсуждения на эту тему c:

1 Ответ

3 голосов
/ 05 февраля 2020

Ваше наблюдение верно - это поведение. Причина в том, что существуют факторы, которые могут зависеть от других полей (например, через директиву copyField), от того, как объединяются поля (приращение позиции и т. Д. c.), И поэтому частичное обновление возможно только с сохраненными полями - документ просто загружается, значение этого поля c обрабатывается, а затем снова индексируется.

Поля не имеют своих собственных файлов для своих индексов - это один набор файлов для полного индекса, и индекс только добавляется - документы в этом индексе не изменяются на месте (поэтому документ только помечается как удаленный, а затем новый документ добавляется в указатель). Когда вы запускаете optimize для индекса, индекс перезаписывается без присутствия удаленных документов.

Существует способ обойти это, и , если ваше поле заполняет набор условий , и обновление на месте может быть выполнено вместо . Это делает то, что вы просите.

Обновления на месте очень похожи на обновления atomi c; в некотором смысле это подмножество обновлений atomi c. При регулярных обновлениях atomi c весь документ переиндексируется внутри во время применения обновления. Однако в этом подходе затрагиваются только поля, подлежащие обновлению, а остальные документы не переиндексируются внутри . Следовательно, на эффективность обновления на месте не влияет размер обновляемых документов (т. Е. Количество полей, размер полей и т. Д. c.). Помимо этих внутренних различий, нет никаких функциональных различий между обновлениями atomi c и обновлениями на месте.

Однако требования могут не соответствовать вашему варианту использования - то есть они должны быть не indexed и Numberri c (так как заменяется docValue в фоновом режиме, а не содержимое в индексе - где эта операция в общем случае невозможна - только индекс добавляется):

Операция обновления Atomi c выполняется с использованием этого подхода только в том случае, если обновляемые поля удовлетворяют следующим трем условиям:

  • не индексируются (indexed = "false"), не сохраняются ( сохраненные = "false"), однозначные (multiValued = "false") числовые c docValues ​​(docValues ​​= "true") поля;
  • поле версия также не является индексированное, не сохраняемое однозначное поле docValues; и
  • копировать цели обновленных полей, если они есть, также неиндексированные, не сохраняемые однозначные числовые поля c docValues.

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

...