Сбой поиска Hibernate с двойным типом больше 5 цифр - PullRequest
2 голосов
/ 15 февраля 2011

У меня есть следующие поля на объекте:

@Field(index = Index.TOKENIZED, store = Store.YES)
@Column(name = "total_credit_amount", nullable = false)
@FieldBridge(impl = RoundedDoubleBridge.class)
private Double totalCreditAmount;

@Field(index = Index.TOKENIZED, store = Store.YES)
@Column(name = "total_debit_amount", nullable = false)
@FieldBridge(impl = RoundedDoubleBridge.class)
private Double totalDebitAmount;

Реализация моста Double-String следующая:

public class RoundedDoubleBridge
    implements StringBridge
{
@Override
    public String objectToString(Object value)
    {
        // Do not index null strings
        if (value == null)
        {
            return null;
        }

        if (value instanceof Double)
        {
            long price = round((Double) value);

            return Long.toString(price);
        }
        else
        {
            throw new IllegalArgumentException(
                RoundedDoubleBridge.class + " used on a non double type: "
                + value.getClass());
        }
    }


    private long round(double price)
    {
        double rounded = Math.floor(price / 3) * 3;

        if (rounded != price)
        {
            rounded += 3; //we round up
        }

        return (long) rounded;
    }
}

Итак, проблема в том, что поисквыполнение получения результатов всякий раз, когда значения на totalDebitAmount или totalCreditAmount меньше 100000, когда они больше или равны 100000, поиск не удался. Любая помощь приветствуется.

Вот способ, которым я выполняю поиск:

public List<AbstractRecord> doSearch(String stringToFind)
    {
        List<AbstractRecord> result = null;

        // Test Search for specific values of an Abstract Record
        // Aim to return the number of retreived results
        em = emf.createEntityManager();

        FullTextEntityManager fullTextEntityManager =
            org.hibernate.search.jpa.Search.getFullTextEntityManager(em);

        //em.getTransaction().begin();
        String[] fields = // Fields to be reviewed
            new String[]
            {
               ....,
               "totalCreditAmount", "totalDebitAmount",
               ....
            };

        //Create a multi-field Lucene query
        StandardAnalyzer stdAnalyzer = new StandardAnalyzer(Version.LUCENE_30);
        MultiFieldQueryParser parser =
            new MultiFieldQueryParser(Version.LUCENE_30, fields, stdAnalyzer);
        org.apache.lucene.search.Query query = null;

        try
        {
            query = parser.parse(stringToFind);
        }
        catch (ParseException ex)
        {
            Logger.getLogger(SearchFacade.class.getName()).log(Level.SEVERE, null, ex);
        }

        long time1 = System.currentTimeMillis();

        // Wrap Lucene query in a javax.persistence.Query
        javax.persistence.Query persistenceQuery =
            fullTextEntityManager.createFullTextQuery(query);
        // Execute search
        result = (List<AbstractRecord>) persistenceQuery.getResultList();
        em.close();

        return result;
    }

1 Ответ

1 голос
/ 16 февраля 2011

Ну, я чувствую себя немного глупо.Я нашел свою проблему .. Именно в функции округления реализации моего FieldBridge Соответствующий фрагмент моста выглядит следующим образом:

private long round(double price)
    {
        double rounded = Math.floor(price / 3) * 3;

        if (rounded != price)
        {
            rounded += 3; //we round up
        }

        return (long) rounded;
    }

Примечание для цены = 100000переменная округлено = 99999 После проверки условия if, поскольку оно отличается от цены, оно добавит 3, следовательно, индексируя 100002 вместо 100000, поэтому, если я посмотрю на 100002, я найду соответствующую запись ..

Уроки, извлеченные здесь:

  • Если вы реализуете настроенный DoubleBridge , чтобы пэды и / или округления обеспечивали соответствие функции округления всем диапазонам значений данных, чтобы избежать проблемкак тот, который у меня был ..
  • Если вам нужно показать на экране округленные двойные числа в простой записи, а не научную, вам нужно будет реализовать TwoWayStringBridge , который выполняет ObjectToString заполнение и округление преобразования, а затем преобразование StringToObject , возвращающее простое notation Double, а не в его научной нотации.

Надеюсь, этот пост может помочь любому с похожими проблемами.Поздравил

...