Как создать уникальный идентификатор с помощью Lucene? - PullRequest
6 голосов
/ 20 февраля 2011

Я использую Lucene для хранения (а также индексирования) различных документов.

Каждый документ нуждается в постоянном уникальном идентификаторе (для использования в качестве части URL).

Если бы я использовал базу данных SQL, я мог бы использовать поле integer primary key auto_increment (или подобное), чтобы автоматически генерировать уникальный идентификатор для каждой добавленной записи.

Есть ли способ сделать это с Lucene?

Мне известно, что документы в Lucene пронумерованы, но отметили, что эти числа перераспределяются с течением времени.

(я использую Java-версию Lucene 3.0.3.)

Ответы [ 4 ]

4 голосов
/ 21 февраля 2011

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

Остается проблема постоянства - как сохранить максимальный идентификатор при остановке процесса Lucene. Одна возможность - использовать текстовый файл, который сохраняет максимальный идентификатор.

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

2 голосов
/ 22 февраля 2011

Для подобных ситуаций я использую следующий алгоритм (не имеет ничего общего с Lucene, но вы можете использовать его в любом случае).

  • Создать новый AtomicLong. Начните с начального значения, полученного из System.currentTimeMillis() или System.nanoTime()
  • Каждый следующий идентификатор генерируется путем вызова .incrementAndGet или .getAndIncrement для этого AtomicLong.
  • если система перезагружается, AtomicLong снова инициализируется в текущую метку времени при запуске.

Плюсы: простой, эффективный, поточно-ориентированный, неблокирующий. Если вам нужна поддержка кластеризованных идентификаторов, просто добавьте место для алгоритма hi / lo поверх существующего long или пожертвуйте несколько старших байтов.

Минусы: не работает, если частота добавления новых сущностей превышает 1 / мс (для System.currentTimeMillis()) или 1 / нс (для System.nanoTime()). Не переносит отклонения часов.

Можно рассмотреть возможность использования UUID в качестве еще одной альтернативы. Вероятность дублирования в UUID практически не существует .

0 голосов
/ 28 декабря 2015

Попробуйте найти уникальное значение в источнике данных, который вы индексируете, и сохраните его в документе lucene. Источником данных может быть база данных mysql, файлы из файловой системы и т. Д.

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

Допустим, вы индексируете из двух таблиц 'pages' и 'comments' table; для каждой строки в таблице страниц вы можете сгенерировать уникальный идентификатор, используя «page_28» для строки с идентификатором 28 в вашей таблице страниц. Точно так же, допустим, вы индексировали строку 36 в таблице комментариев, ваш уникальный идентификатор будет «comment_36».

Если все параметры потерпят неудачу, я буду придерживаться UUID. При некоторой дополнительной паранойе это может быть UUID, добавленный к метке времени now ().

0 голосов
/ 20 февраля 2011

РЕДАКТИРОВАТЬ : Некоторые комментаторы подняли возможные проблемы с этим подходом, и у меня нет времени, чтобы тщательно его протестировать. Я оставляю это здесь, потому что Yuval F. обращается к этому. Пожалуйста, не понижайте голос без необходимости.

Учитывая IndexWriter w, вы можете использовать w.maxDoc() + 1 в качестве идентификатора и хранить его (в виде строки) в отдельном Field. Убедитесь, что Field хранится .

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