Hibernate Search查询多列

时间:2014-09-04 06:52:30

标签: java mysql lucene hibernate-search

@Entity // mark book class as a entity bean for hibernate
@Indexed // Book as indexable 
@AnalyzerDef(name = "ngram", tokenizer = 
        @TokenizerDef(factory = StandardTokenizerFactory.class), filters = { 
        @TokenFilterDef(factory = StandardFilterFactory.class), 
        @TokenFilterDef(factory = LowerCaseFilterFactory.class),
        @TokenFilterDef(factory = StopFilterFactory.class), 
        @TokenFilterDef(factory = SnowballPorterFilterFactory.class,
            params = { @Parameter(name = "language", value = "English") }),
        @TokenFilterDef(factory = NGramFilterFactory.class, params = {
                @Parameter(name = "minGramSize", value = "3"),
                @Parameter(name = "maxGramSize", value = "6") }) })
public class Book {

    @Id 
    @GeneratedValue 
    private Integer id;

    @Field(index = Index.YES,store= Store.YES)
    @FieldBridge(impl = PaddedIntegerBridge.class,params = @Parameter(name="padding", value="10"))
    private int isbnNo;


    @Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO, analyzer = @Analyzer(definition = "ngram"))
    private String title;

//And getter setter 
}


public class PaddedIntegerBridge implements TwoWayStringBridge, ParameterizedBridge {

    public static String PADDING_PROPERTY = "padding";
    private int padding = 5; //default

    public void setParameterValues(Map parameters) {
        Object padding = parameters.get( PADDING_PROPERTY );
        String pad = (String) padding;
        if (padding != null) this.padding = Integer.parseInt(pad);
    }

    public String objectToString(Object object) {
        String rawInteger = ( (Integer) object ).toString();
        if (rawInteger.length() > padding) 
            throw new IllegalArgumentException( "Try to pad on a number too big" );
        StringBuilder paddedInteger = new StringBuilder( );
        for ( int padIndex = rawInteger.length() ; padIndex < padding ; padIndex++ ) {
            paddedInteger.append('0');
        }
        return paddedInteger.append( rawInteger ).toString();
    }

    public Object stringToObject(String stringValue) {
        return new Integer(stringValue);
    }
}

我想在两个可搜索的列上编写查询,即isbnNo和title。

QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Book.class).get();
org.apache.lucene.search.Query query = qb.keyword().onField("isbnNo").andField("title").ignoreFieldBridge().matching("hiber").createQuery();

当我尝试使用1000或整数值进行搜索时,它起作用,因为我在标题字段上添加了ignoreFieldBridge。但是如果我在匹配中使用字符串参数,它会为上面的查询提供classCastException。 我只有单个文本框用于搜索。我应该能够搜索整数no以及任何字符串值。名称为flipkart搜索框

2 个答案:

答案 0 :(得分:3)

    String searchable;
    org.apache.lucene.search.Query query = qb.bool()
                              .should( qb.keyword().onField("title").ignoreFieldBridge().matching(searchable).createQuery() )
                              .should( qb.keyword().onField("isbnNo").ignoreAnalyzer().matching(searchable).createQuery() )
                            .createQuery();

我得到了解决方案bool操作是在关键字上给出的,可以用于多列查询

答案 1 :(得分:0)

  

您可以像以下一样应用andField方法:

Query q = builder.keyword().onField("stock_name").andField("stock_code").andField("stock_date").matching(searchQuery).createQuery();
     

见下面的例子:

Session session = HibernateUtil.getSession();

FullTextSession fullTextSession  = org.hibernate.search.Search.getFullTextSession(session);

QueryBuilder builder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Stock.class).get();

Query q = builder.keyword().onField("stock_name").andField("stock_code").matching(searchQuery).createQuery();

org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery(q, Stock.class);

List list = fullTextQuery.list();