2

エンティティに次のフィールドがあります。

@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;

DoubletoStringブリッジの実装は次のとおりです。

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;
    }
4

1 に答える 1

1

うーん、私はちょっとばかげているように感じます。私は私の問題を見つけました..それは具体的には私の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 が追加されます。したがって、100000 ではなく 100002 をインデックス付けします。したがって、100002 を検索すると、適切なレコードが見つかります。

ここで学んだ教訓:

  • パディングや丸めを行うカスタマイズされた DoubleBridgeを実装している場合は、丸め関数がすべてのデータ値の範囲を満たしていることを確認して、私が経験したような問題を回避してください。
  • 科学的表記法ではなく単純な表記法で切り上げられた Double を画面に表示する必要がある場合は、 ObjectToString変換のパディングと丸め を実行し、後でStringToObject変換で科学的表記法ではなく単純な表記法 Double を返すTwoWayStringBridgeを実装する必要があります。

この投稿が同様の問題を抱えている人に役立つことを願っています。あいさつ

于 2011-02-16T13:22:46.360 に答える