Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate搜索以查找短语的部分匹配项_Java_Hibernate_Lucene_Hibernate Search_Solar - Fatal编程技术网

Java Hibernate搜索以查找短语的部分匹配项

Java Hibernate搜索以查找短语的部分匹配项,java,hibernate,lucene,hibernate-search,solar,Java,Hibernate,Lucene,Hibernate Search,Solar,在我的项目中,我们将HibernateSearch4.5与lucene分析器和solar一起使用。 我为我的客户提供一个文本字段。当他们输入一个短语时,我希望找到名称中包含给定短语的所有用户实体 例如考虑数据库中的条目列表,标题如下: [ Alan Smith, John Cane, Juno Taylor, Tom Caner Junior ] jun应该归还Juno Taylor和Tom Caner Junior 阿兰·史密斯、约翰·凯恩和小汤姆·凯恩应该会回来 我尝试过通配符搜索,但是

在我的项目中,我们将HibernateSearch4.5与lucene分析器和solar一起使用。 我为我的客户提供一个文本字段。当他们输入一个短语时,我希望找到名称中包含给定短语的所有用户实体

例如考虑数据库中的条目列表,标题如下:

[ Alan Smith, John Cane, Juno Taylor, Tom Caner Junior ]
jun应该归还Juno Taylor和Tom Caner Junior

阿兰·史密斯、约翰·凯恩和小汤姆·凯恩应该会回来

我尝试过通配符搜索,但是

如何实现这一点?

为什么不使用标准的TypedQuery

其中字符串术语是您的搜索术语

TypedQuery<Student> q = em.createQuery(
        "SELECT s " +
        "FROM Student s " +
        "WHERE s.fname like :search " +
        "OR s.lname like :search";
q.setParameter("search", "%" + term + "%");
没有测试这个,但是类似的东西应该可以做到。

为什么不使用标准的TypedQuery

其中字符串术语是您的搜索术语

TypedQuery<Student> q = em.createQuery(
        "SELECT s " +
        "FROM Student s " +
        "WHERE s.fname like :search " +
        "OR s.lname like :search";
q.setParameter("search", "%" + term + "%");

没有测试这个,但是类似的东西应该可以做到。

首先,您没有将分析器分配给您的字段,因此当前没有使用它。您应该使用@Field.analyzer

其次,为了回答您的问题,最好使用Edgengram过滤器分析此类文本。您应该将此筛选器添加到analyzer定义中

编辑:另外,为了防止诸如sathya之类的查询与sanchana匹配,例如,在查询时应该使用不同的分析器

下面是一个完整的例子

@AnalyzerDef(name = "customanalyzer", tokenizer = @TokenizerDef(factory = WhitespaceTokenizerFactory.class), filters = {
        @TokenFilterDef(factory = LowerCaseFilterFactory.class),
        @TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = { @Parameter(name = "language", value = "English") })
        @TokenFilterDef(factory = EdgeNGramFilterFactory.class, params = { @Parameter(name = "maxGramSize", value = "15") })

})
@AnalyzerDef(name = "customanalyzer_query", tokenizer = @TokenizerDef(factory = WhitespaceTokenizerFactory.class), filters = {
        @TokenFilterDef(factory = LowerCaseFilterFactory.class),
        @TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = { @Parameter(name = "language", value = "English") })

})
public class Student implements Serializable {

    @Column(name = "Fname")
    @Field(index = Index.YES, store = Store.YES, analyze = Analyze.YES, analyzer = @Analyzer(definition = "customanalyzer"))
    private String fname;

    @Column(name = "Lname")
    @Field(index = Index.YES, store = Store.YES, analyze = Analyze.YES, analyzer = @Analyzer(definition = "customanalyzer")))
    private String lname;

}
然后特别提到在构建查询时要使用此查询分析器:

QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Student.class)
    // Here come the assignments of "query" analyzers
    .overridesForField( "fname", "customanalyzer_query" )
    .overridesForField( "lname", "customanalyzer_query" )
    .get();
// Then it's business as usual
Query luceneQuery = queryBuilder.keyword().onFields("fname", "lname").matching("sathya").createQuery();
FullTextQuery query = fullTextEntityManager.createFullTextQuery(luceneQuery, Student.class);
另见:


顺便说一句,如果您的数据只包括名字和姓氏,您不应该使用词干分析SnowballPorterFilterFactory:这只会使搜索不太准确,没有什么好的理由。

首先,您没有将分析器分配给字段,因此当前没有使用它。您应该使用@Field.analyzer

其次,为了回答您的问题,最好使用Edgengram过滤器分析此类文本。您应该将此筛选器添加到analyzer定义中

编辑:另外,为了防止诸如sathya之类的查询与sanchana匹配,例如,在查询时应该使用不同的分析器

下面是一个完整的例子

@AnalyzerDef(name = "customanalyzer", tokenizer = @TokenizerDef(factory = WhitespaceTokenizerFactory.class), filters = {
        @TokenFilterDef(factory = LowerCaseFilterFactory.class),
        @TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = { @Parameter(name = "language", value = "English") })
        @TokenFilterDef(factory = EdgeNGramFilterFactory.class, params = { @Parameter(name = "maxGramSize", value = "15") })

})
@AnalyzerDef(name = "customanalyzer_query", tokenizer = @TokenizerDef(factory = WhitespaceTokenizerFactory.class), filters = {
        @TokenFilterDef(factory = LowerCaseFilterFactory.class),
        @TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = { @Parameter(name = "language", value = "English") })

})
public class Student implements Serializable {

    @Column(name = "Fname")
    @Field(index = Index.YES, store = Store.YES, analyze = Analyze.YES, analyzer = @Analyzer(definition = "customanalyzer"))
    private String fname;

    @Column(name = "Lname")
    @Field(index = Index.YES, store = Store.YES, analyze = Analyze.YES, analyzer = @Analyzer(definition = "customanalyzer")))
    private String lname;

}
然后特别提到在构建查询时要使用此查询分析器:

QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Student.class)
    // Here come the assignments of "query" analyzers
    .overridesForField( "fname", "customanalyzer_query" )
    .overridesForField( "lname", "customanalyzer_query" )
    .get();
// Then it's business as usual
Query luceneQuery = queryBuilder.keyword().onFields("fname", "lname").matching("sathya").createQuery();
FullTextQuery query = fullTextEntityManager.createFullTextQuery(luceneQuery, Student.class);
另见:


顺便说一句,如果您的数据只包括名字和姓氏,则不应使用词干分析SnowballPorterFilterFactory:这只会使搜索不太准确,没有什么好的理由。

类似SQL的运算符非常有限。问题是如何使用适当的全文,这样可以非常灵活地控制如何匹配/匹配什么,而且性能也会好得多。问题是如何使用适当的全文,它允许非常灵活地控制如何匹配/匹配什么,并且恰好性能更好。我已经在类级别添加了分析器,现在我已经更新了。我已经尝试了您建议的EdgeNGramTokenFilter.class,现在问题是什么意思,如果我用Sathya搜索它给出的结果,比如sandhya、saravanan、sachin、sanchana和Sathya。但我不知道其他的名字。它应该像“%sathya%”一样搜索。你能推荐其他的过滤器吗。提前谢谢。@PSKumar好的,您应该在查询时使用不同的分析器。我更新了我的答案。qb来自哪里,我试图用同样的方法,但qb不是defined@Tanah我修复了这个例子,qb应该是queryBuilderI在类级别添加了分析器,现在我已经更新了。我已经尝试了您建议的EdgeNGramTokenFilter.class,现在问题是什么意思,如果我用Sathya搜索它给出的结果,比如sandhya、saravanan、sachin、sanchana和Sathya。但我不知道其他的名字。它应该像“%sathya%”一样搜索。你能推荐其他的过滤器吗。提前谢谢。@PSKumar好的,您应该在查询时使用不同的分析器。我更新了我的答案。qb来自哪里,我试图用同样的方法,但qb不是defined@Tanah我修正了这个例子,qb应该是queryBuilder