zoukankan      html  css  js  c++  java
  • 搜索

    1.1 JPA配置

    spring bean配置文件中
    org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
    的jpaProperties属性集合增加如下配置:

    <prop key="hibernate.search.autoregister_listeners">true</prop>
    <prop key="hibernate.search.default.directory_provider">filesystem</prop>
    <prop key="hibernate.search.default.indexBase">lucene/indexes</prop>
    <prop key="hibernate.search.default_null_token">_null_</prop>


    autoregister_listeners:自动注册监听器,即在hibernate监听到对象插入、更新、删除时自动更新对象索引__
    directory_provider:可选值包括ram、filesystem等,具体可参考官方文档__
    indexBase:对应上一项配置为filesystem,设定索引存放的根路径。__
    default_null_token:默认空值标记,此项默认值即为_null_可以不用配置__

    ## 1.2 索引实体注解配置

    ### @Indexed

    index属性指定索引名称(也对应于文件系统中目录名称),不指定默认类的全名。示例:

    @Indexed(index="requirement")
    public class Requirement extends Backlog {
    ...
    }

    ### @DocumentId

    用于保证索引实体的唯一性。注解在主键上。采用JPA方式时,如果指定了@Id则不再需要标注该注解。


    ### @Field

    index 指定是否索引,默认Index.YES
    analyze 是否分析(分词器进行分词),默认Analyze.YES,目前对于不会搜索值的片段的字段都设置为了NO
    store是否存储,默认Store.NO,设置为YES将占用索引空间,但支持投影,即直接从索引库得到字段值。

    示例

    @Field(index = Index.YES, analyze = Analyze.NO, store = Store.YES)
    private String type;

    @Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
    private String descr;


    ### @IndexedEmbedded

    对需要索引的关联对象采用此注解

    @IndexedEmbedded(indexNullAs = IndexedEmbedded.DEFAULT_NULL_TOKEN)
    private User assignee;

    indexNullAs = IndexedEmbedded.DEFAULT_NULL_TOKEN,当关联对象是空时,存储为配置的null标记,默认不存储,根据实际需要配置此项(是否要根据空值进行查询)。

    ### @DateBridge
    日期格式存储桥接转换
    resolution = org.hibernate.search.annotations.Resolution.SECOND,存储到秒,可选:
    1) Resolution.DAY
    2) Resolution.HOUR
    3) Resolution.MILLISECOND
    4) Resolution.MINUTE
    5) Resolution.MONTH
    6) Resolution.SECOND
    7) Resolution.YEAR

    # 2.API

    官方文档Example 1.9中一个完整的简单例子

    EntityManager em = entityManagerFactory.createEntityManager();
    FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
    em.getTransaction().begin();

    // create native Lucene query unsing the query DSL
    // alternatively you can write the Lucene query using the Lucene query parser
    // or the Lucene programmatic API. The Hibernate Search DSL is recommended though
    QueryBuilder qb = fullTextEntityManager.getSearchFactory()
    .buildQueryBuilder().forEntity( Book.class ).get();
    org.apache.lucene.search.Query query = qb
    .keyword()
    .onFields("title", "subtitle", "authors.name")
    .matching("Java rocks!")
    .createQuery();

    // wrap Lucene query in a javax.persistence.Query
    javax.persistence.Query persistenceQuery =
    fullTextEntityManager.createFullTextQuery(query, Book.class);

    // execute search
    List result = persistenceQuery.getResultList();

    em.getTransaction().commit();
    em.close();

    **需要注意的是搜索必须包含在一个事务内,比如搜索方法上需要有@Transactional的注解。**
    ## 2.1 Query API
    ###QueryBuilder
    FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
    QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(entityClass).get();

    ###关键字查询

    Query luceneQuery = qb.keyword().onField("descr").matching("搜索").createQuery();
    keyword()方法意味着你正在尝试着去查询一个指定的词语。onField()方法指定查询哪个Lucene field。matching()方法告诉查询哪个词语。最后createQuery()方法创建Lucene query对象

    ###语句查询

    Query luceneQuery = qb.phrase().onField("descr").matching("过滤器").createQuery();

    目前主要使用此查询,因为使用keyword查询用目前默认标准分析器,查询“我们”与“们我”都会得到相同的结果

    ###通配符查询

    Query luceneQuery = qb.keyword().wildcard().onField("id").matching("*").createQuery();
    用于返回全部记录

    ###范围查询

    TermRangeQuery query = new TermRangeQuery(field,20090101","20090105",true,true);
    最后两个参数分别为是否包含起始值,目前主要用于日期范围搜索。

    ###组合查询

    BooleanQuery boolQuery = new BooleanQuery();
    boolQuery.add(lucenequery,Occur.MUST);
    ...
    SHOULD: query之间是或关系。
    MUST:query之间是并关系。
    MUST NOT:必须不包含该query。

    ###分页

    FullTextQuery ftQuery = fullTextEntityManager.createFullTextQuery(boolQuery, Backlog.class);
    ftQuery .setFirstResult(15); //从第几条记录开始
    ftQuery .setMaxResults(10); //返回几条记录

    ###排序

    ftQuery.setSort(new Sort(new SortField("updated", SortField.STRING, true)));

    ###返回结果

    ftQuery.getResultList();


    ## 2.2 结果转换及排序特殊处理

    ### 结果转换
    由于索引中存储关联对象时,只保存了键值,搜索结果返回前端时需要转换为相应对象,故利用hibernate提供的ResultTransformer接口进行扩展,定义了BacklogSearchResultTransformer接口及相应实现类HtmlResultTransformerImpl(已弃用)及ObjectResultTransformerImpl进行搜索结果的逐项转换。
    使用示例如下:

    FullTextQuery ftQuery = fullTextEntityManager.createFullTextQuery(andQuery, entityClass);
    if (resultTransformer != null) {
    ftQuery.setResultTransformer(resultTransformer);
    }
    在调用getResultList()时会调用转换类相应方法进行转换。另外需要注意的是接口使用之间要调用接口的initDictTranslateMap方法进行初始化数据的准备,并且是每次调用前都要执行。
    ###排序
    同样由于索引中存储关联对象只保存了键值,如果按相应关联对象进行排序时,如果不进行处理则实际上是按相应的键值(id)进行排序而不是根据相应的名称,因此在LuceneSortFieldFactory的基础上扩展了BacklogSortFieldFactory进行了相应排序字段的排序处理。
    使用示例如下:

    Sort sort = new Sort(sortFieldFactory.createSortField(pageAndSort.getSortField(), pageAndSort.isDesc()));
    ftQuery.setSort(sort);

  • 相关阅读:
    leetcode_09_Palindrome Number (easy)
    JQuery与JavaScript与Ajax三者的区别与联系
    Blockly常用函数
    JavaWeb中四大域对象
    Thymeleaf知识
    列表、字典、元组、集合的区别
    Spring Boot拦截器
    AWS路由表
    Android调试工具DDMS的使用详解
    Android 列表单选对话框
  • 原文地址:https://www.cnblogs.com/suncj/p/4256645.html
Copyright © 2011-2022 走看看