Lucene BigDecimal Range Query - PullRequest
       36

Lucene BigDecimal Range Query

0 голосов
/ 26 февраля 2020

В моем классе сущности определено следующее поле:

@Column
@FieldBridge(impl = BigDecimalNumericFieldBridge.class)
@Fields(
  @Field(),
  @Field(name = "test_sort", analyze = Analyze.NO, store = Store.NO, index = Index.NO))
@NumericField
@SortableField(forField = "test_sort")
val test: BigDecimal

Мой класс BigDecimalNumericFieldBridge использует реализацию, описанную в документации: https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#example -custom-numericfieldbridge и в форумы здесь: https://discourse.hibernate.org/t/sorting-on-bigdecimal-field/2339

Я использую собственный анализатор запросов, чтобы преобразовать запрос в числовой c запрос диапазона так:

override fun newRangeQuery(field: String, part1: String, part2: String, startInclusive: Boolean, endInclusive: Boolean) {
  if ("test" == field) {
    val convertedPart1 = BigDecimal(part1).multiply(storeFactor).longValueExact()
    val convertedPart2 = BigDecimal(part2).multiply(storeFactor).longValueExact()
    return NumericRangeQuery.newLongRange(field, convertedPart1, convertedPart2, startInclusive, endInclusive)
  }

  return super.newRangeQuery(field, part1, part2, startInclusive, endInclusive)
}

Все запросы, которые я делаю в этом поле, возвращают ноль результатов, даже если я делаю диапазон от 0 до 999999999999, который, как я знаю, включает все значения. Если я оставляю это как поиск строки, я получаю следующую ошибку: «содержит подзапрос на основе строки, который нацелен на поле цифр c». Сортировка на полевых работах. Что мне не хватает? Заранее благодарим за помощь.

Редактировать Добавление лога полевого моста c:

class BigDecimalNumericFieldBridge : TwoWayFieldBridge {

  override fun get(name: String, document: Document): Any? {
    val fromLucene: String = document.get(name) ?: ""

    if (fromLucene.isNotBlank()) {
      return fromLucene.toBigDecimal().divide(LUCENE_BIG_DECIMAL_STORE_FACTOR)
    }

    return null
  }

  override fun set(name: String, value: Any?, document: Document, options: LuceneOptions) {
    if (value != null && name == "test_sort") {
      val decimalValue: BigDecimal = value as BigDecimal
      val indexedValue: Long = decimalValue
          .multiply(LUCENE_BIG_DECIMAL_STORE_FACTOR)
          .longValueExact()
      options.addNumericFieldToDocument(name, indexedValue, document)
      options.addNumericDocValuesFieldToDocument(name, indexedValue, document)
    }
  }

  override fun objectToString(obj: Any?): String {
    return obj.toString()
  }
}

Ответы [ 2 ]

0 голосов
/ 27 февраля 2020

Добавление обоих полей в функцию set логи моста моста c решает проблему Теперь мои поиски работают. Я думаю, это заставляет меня задуматься, нужны ли мне два отдельных определения полей. Я думаю, что мне не помешает только одна аннотация @Field, и тогда мне не нужно будет хранить и test, и test_sort.

Вы, вероятно, ссылаетесь на поле test в своем роде. Если ваше поле сортировки называется test_sort, вы должны использовать это имя при создании сортировки в поисковом запросе.

0 голосов
/ 26 февраля 2020

Добавление обоих полей в функцию set полевого моста logi c устраняет проблему:

if (value != null && (name == "test" || name == "test_sort")) {

Теперь мой поиск работает. Я думаю, это заставляет меня задуматься, нужны ли мне два отдельных определения полей. Я думаю, что мне не помешает только одна @Field аннотация, и тогда мне не нужно будет хранить и test, и test_sort.

...