如何在hibernate搜索中提升整个术语的出现次数

时间:2017-02-24 10:59:18

标签: java hibernate search lucene hibernate-search

对于像这样的定义

@AnalyzerDef(name = "standard", charFilters = {
    @CharFilterDef(factory = HTMLStripCharFilterFactory.class) },
    tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
    filters = {
        @TokenFilterDef(factory = StandardFilterFactory.class),
        @TokenFilterDef(factory = LowerCaseFilterFactory.class),
        @TokenFilterDef(factory = StopFilterFactory.class, params = {
            @Parameter(name = "words", value = "/org/apache/lucene/analysis/snowball/english_stop.txt")}),
        @TokenFilterDef(factory = EdgeNGramFilterFactory.class, params = {
            @Parameter(name = "maxGramSize", value = "1"),
            @Parameter(name = "maxGramSize", value = "15")})
    }),

我有两个文件,例如54565459 In the Jungle,搜索字词如5459我想将第二个文档返回到结果中的第一个文档。但是第二个fieldNorm低于第一个。

如果文档中出现整个搜索字词与仅部分显示的文档相比,如何提升文档?

我认为这看起来很相似https://docs.jboss.org/hibernate/search/5.6/reference/en-US/html_single/#_customizing_lucene_s_scoring_formula

2 个答案:

答案 0 :(得分:0)

/**
 * Disables effect of lengthNorm
 */
public class CustomSimilarity extends ClassicSimilarity
{
    public float lengthNorm(FieldInvertState state) {
        return state.getBoost();
    }
}

在春天yaml config

spring.jpa.properties.hibernate.search.default.similarity : com.example.search.CustomSimilarity

答案 1 :(得分:0)

我会使用两个字段,一个没有ngrams并且有所提升,另一个有ngrams但没有提升。

@AnalyzerDefs({
    @AnalyzerDef(
        name = "ngram",
        charFilters = {
            @CharFilterDef(factory = HTMLStripCharFilterFactory.class)
        },
        tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
        filters = {
            @TokenFilterDef(factory = StandardFilterFactory.class),
            @TokenFilterDef(factory = LowerCaseFilterFactory.class),
            @TokenFilterDef(factory = StopFilterFactory.class, params = {
                @Parameter(name = "words", value = "/org/apache/lucene/analysis/snowball/english_stop.txt")}),
            @TokenFilterDef(factory = EdgeNGramFilterFactory.class, params = {
                @Parameter(name = "maxGramSize", value = "1"),
                @Parameter(name = "maxGramSize", value = "15")
            })
        }
    ),
    @AnalyzerDef(
        name = "standard",
        charFilters = {
            @CharFilterDef(factory = HTMLStripCharFilterFactory.class)
        },
        tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
        filters = {
            @TokenFilterDef(factory = StandardFilterFactory.class),
            @TokenFilterDef(factory = LowerCaseFilterFactory.class),
            @TokenFilterDef(factory = StopFilterFactory.class, params = {
                @Parameter(name = "words", value = "/org/apache/lucene/analysis/snowball/english_stop.txt")})
        }
    ),
})
@Indexed
@Entity
public class MyEntity {

    @Fields({
        @Field("myfield_ngram", analyzer = @Analyzer(definition = "ngram")),
        @Field("myfield_standard", analyzer = @Analyzer(definition = "standard"))
    })
    private String myField;

    // ...
}

然后以这种方式查询:

QueryBuilder qb = fullTextSession.getSearchFactory()
        .buildQueryBuilder()
        .forEntity( MyEntity.class )
        .overridesForField( "myField_ngram", "standard" ) // Don't generate ngrams when querying, it serves no purpose
        .get();
Query query = qb.keyword()
        .onField( "myField_standard" ).boostedTo(2.0f)
        .andField( "myField_ngram" )
        .matching( "5459 In the Jungle" )
        .createQuery();

免责声明:我没有测试此代码。