[Solr] Apache Solr 入门案例

前言

在上文中我们已经详细介绍了 Solr 的部署 ,本文我们将介绍 Solr 在 Java 中的使用。

上文传送门 :

[Solr] Apache Solr 简介及使用

[Solr] Apache Solr 集群


环境准备

索引库 schema.xml 配置文件


<schema name="example" version="1.5">
   <field name="_version_" type="long" indexed="true" stored="true"/>
   <field name="_root_" type="string" indexed="true" stored="false"/> 
   <field name="id" type="string" indexed="true" 
                    stored="true" required="true" multiValued="false" /> 
   <field name="name" type="text_ws" indexed="true" stored="true"/>
   <field name="price"  type="float" indexed="true" stored="true"/>
   <field name="title" type="text_ws" indexed="true" stored="true" multiValued="false"/>
   <field name="content" type="text_ws" indexed="true" stored="true" multiValued="false"/>
   <field name="text" type="text_ws" indexed="true" stored="true" multiValued="true"/>
   <field name="date"  type="date" indexed="true" stored="true"/>
   <field name="binary"  type="binary" indexed="true" stored="true"/>

   <dynamicField name="*_ss" type="string"  indexed="true"  
                                stored="true" multiValued="true"/>

   <uniqueKey>iduniqueKey>

   <copyField source="title" dest="text"/>
   <copyField source="content" dest="text"/>

    <fieldType name="string" class="solr.StrField" sortMissingLast="true" />
    <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
    <fieldType name="int" class="solr.TrieIntField" 
                        precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="float" class="solr.TrieFloatField" 
                        precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="long" class="solr.TrieLongField" 
                        precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="double" class="solr.TrieDoubleField" 
                        precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="date" class="solr.TrieDateField" 
                        precisionStep="0" positionIncrementGap="0"/>
    <fieldtype name="binary" class="solr.BinaryField"/>


    <fieldType name="text_ws" class="solr.TextField">
        <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
    fieldType>
schema>

入门案例

1> 引入pom相关jar
<dependency>
    <groupId>junitgroupId>
    <artifactId>junitartifactId>
dependency>
<dependency>
    <groupId>org.apache.solrgroupId>
    <artifactId>solr-solrjartifactId>
    <version>4.10.2version>
dependency>

<dependency>
    <groupId>commons-logginggroupId>
    <artifactId>commons-logging-apiartifactId>
    <version>1.1version>
dependency>
2> 初始化SolrServer
    private static String URL = "http://hadoop1:8080/solr/collection3";

    private static SolrServer solrServer =
            new HttpSolrServer(URL);
3> 创建文档

创建一个文档

@Test
public void addSolrDoc () throws IOException, SolrServerException {
    SolrInputDocument document = new SolrInputDocument();
    // 设置激励因子,默认是1
    document.setDocumentBoost(1);
    document.addField("id", "1");
    document.addField("title","媲美故宫的“铜宫”");
    document.addField("content","雷峰塔、峨眉金顶、灵隐铜殿," +
            "上百件标志性铜建筑让他成为“中国当代铜建筑之父”," +
            "他是中国铜雕领域界唯一一位国家级非遗传承人");
    document.addField("date",new Date());
    document.addField("binary","solr".getBytes());
    solrServer.add(document);
    solrServer.commit();
}

注 :
1 > 在Solr中,一个Document必须包含ID,因为Solr是根据ID维护Document的
2 > 一个Fiele中的name值必须是schema.xml中存在的field,如果不存在该Field,会报错

创建多个文档

@Test
public void addSolrDocs() throws IOException, SolrServerException {
    ArrayList documents = new ArrayList<>();
    for (int i = 1; i <= 10; i++) {
        SolrInputDocument document = new SolrInputDocument();
        // 设置激励因子,默认是1
        document.setDocumentBoost(1);
        document.addField("id", i+"");
        document.addField("title", "媲美故宫的“铜宫”");
        document.addField("content", "雷峰塔、峨眉金顶、灵隐铜殿," +
                "上百件标志性铜建筑让他成为“中国当代铜建筑之父”," +
                "他是中国铜雕领域界唯一一位国家级非遗传承人");
        document.addField("date", new Date());
        document.addField("binary", "solr".getBytes());
        documents.add(document);
    }
    solrServer.add(documents);
    solrServer.commit();
}
4 > 修改文档

其实Solr在修改时,做的依旧是add操作,只不过Solr会根据document的ID来查询此document是否存在,如果存在,会先删除此document,然后执行add操作。

@Test
public void updateSolrDoc () throws IOException, SolrServerException {
    SolrInputDocument document = new SolrInputDocument();
    // 设置激励因子,默认是1
    document.setDocumentBoost(1);
    document.addField("id", 10);
    document.addField("title", "媲美故宫的“铜宫”");
    document.addField("content", "这是修改后的内容");
    solrServer.add(document);
    solrServer.commit();
}

由于上面我们已经批量添加了10条数据,我们执行完修改操作后,在来看看ID为10的Document,发现该Document的date与binary都消息了,证明先执行了删除,后执行了新增。

      {
        "id": "10",
        "title": "媲美故宫的“铜宫”",
        "text": [
          "媲美故宫的“铜宫”",
          "这是修改后的内容"
        ],
        "content": "这是修改后的内容",
        "_version_": 1608276634333347800
      }
5> 使用JavaBean写入文档

注 : 在JavaBean中要对字段加上 @Field 注解,才能被Solr识别

public class SolrDocument {
    @Field
    private String id;
    @Field
    private String name;
    @Field
    private double price;
    @Field
    private String title;
    @Field
    private String content;
    @Field
    private ArrayList text;
    @Field
    private Date date;
    @Field
    private byte[] binary;

    //... get set   
}    
@Test
public void addSolrBean() throws IOException, SolrServerException {
    SolrDocument solrDocument = new SolrDocument();
    solrDocument.setId("11");
    solrDocument.setTitle("媲美故宫的“铜宫”");
    solrDocument.setContent("雷峰塔、峨眉金顶、灵隐铜殿," +
            "上百件标志性铜建筑让他成为“中国当代铜建筑之父”," +
            "他是中国铜雕领域界唯一一位国家级非遗传承人");
    solrDocument.setDate(new Date());
    solrDocument.setBinary("solr".getBytes());
    solrServer.addBean(solrDocument);
    solrServer.commit();
}
6> 删除文档
/**
 * 删除单个Doc
 */
@Test
public void deleteDocById () throws IOException, SolrServerException {
    solrServer.deleteById("11");
    solrServer.commit();
}

/**
 * 删除多个Doc
 */
@Test
public void deleteDocByIds () throws IOException, SolrServerException {
    List ids = new ArrayList<>();
    ids.add("9");
    ids.add("10");
    solrServer.deleteById(ids);
    solrServer.commit();
}

/**
 * 根据查询条件删除
 */
@Test
public void deleteAll() throws IOException, SolrServerException {
    // *:* 删除所有doc
    solrServer.deleteByQuery("*:*");
    solrServer.commit();
}
7> 查询
/**
 * 查询所有DOC,返回Results
 */
@Test
public void selectByDoc () throws SolrServerException {
    SolrQuery query = new SolrQuery("*:*");
    QueryResponse response = solrServer.query(query);
    SolrDocumentList results = response.getResults();
    for (org.apache.solr.common.SolrDocument result : results) {
        String id = (String) result.getFieldValue("id");
        Double price = (Double) result.getFieldValue("price");
        Collection title = result.getFieldValues("title");
        Date date = (Date) result.getFieldValue("date");
        byte[] binary = (byte[]) result.getFieldValue("binary");
    }
}


/**
 * 查询所有DOC,返回JavaBean
 */
@Test
public void selectByJavaBean () throws SolrServerException {
    SolrQuery query = new SolrQuery("*:*");
    QueryResponse response = solrServer.query(query);
    List documents = response.getBeans(SolrDocument.class);
    for (SolrDocument document : documents) {
        System.out.println(document);
    }
} 
  
8> 高级查询
  • 通配符查询
/**
 * 通配符查询
 * ? : 占位符,表示占用一个字符
 * * :占位符,表示占用0到多个字符
 */
@Test
public void wildSelect () throws SolrServerException {
    SolrQuery query = new SolrQuery("content:雷峰?");
    selectByQuery(query);
    query = new SolrQuery("content:雷峰*");
    selectByQuery(query);
}
  • 模糊查询
/**
 * 模糊查询 : 需要在查询的值后面加上~符号
 */
@Test
public void fuzzSelect () throws SolrServerException {
    // 如果不加后面的2,默认就是移位两次
    SolrQuery query = new SolrQuery("content:塔雷峰~2");
    selectByQuery(query);
    // 为了避免用户在输入的值上也输入~,可以将用户输入的值用双引括起来
    query = new SolrQuery("content:\"塔雷峰\"~2");
    selectByQuery(query);
    query = new SolrQuery("content:\"雷峰~\"~2");
    selectByQuery(query);
}
  • 范围查询
/**
 * 范围查询
 * 语法格式 :
 *          1> field:[start TO end]  (包含边界值)
 *          2> field:{start TO end}  (不包含边界值)
 */
@Test
public void rangeSelect () throws SolrServerException {
    // 查询 1、2
    SolrQuery query = new SolrQuery("price:[1 TO 2]");
    selectByQuery(query);
    // 查询 1、2,没有3
    query = new SolrQuery("price:[1 TO 3}");
    selectByQuery(query);
}

注 : 排序的字段最好是数值类型,日期类型等,否则排序出来的结果可能差强人意

  • 组合查询
/**
 * 组合查询 : 可以将多个表达式组合起来一起查询
 * 使用 : AND NOT OR 即可
 *
 * AND : 此条件必须包含
 * NOT : 不能包含此条件里的内容
 * OR  : 可选的,如果有就返回,没有就不管
 */
@Test
public void booleanSelect () throws SolrServerException {
    String term = "price:[1 TO 5] NOT id:1 OR id:8 OR content:\"塔雷峰\"~2";
    SolrQuery query = new SolrQuery(term);
    selectByQuery(query);
}
9> 排序
/**
 * SolrQuery#setSort : [asc|desc]
 */
@Test
public void sortSelect () throws SolrServerException {
    SolrQuery query = new SolrQuery("*:*");
    query.setSort("price", SolrQuery.ORDER.asc);
    selectByQuery(query);
}
10>分页查询
/**
 * 分页查询 :
 * SolrQuery#setStart : 起始点
 * SolrQuery#setRows  : 查询条数
 */
@Test
public void pageSelect () throws SolrServerException {
    SolrQuery query = new SolrQuery("*:*");
    // 从第一条开始查
    query.setStart(0);
    // 共查3条
    query.setRows(3);
    selectByQuery(query);
}
11> 高亮
/**
 * 高亮查询
 */
@Test
public void highSelect() throws SolrServerException {
    SolrQuery query = new SolrQuery("content:雷峰塔");
    query.setHighlight(true);
    //设置高亮字段,可设置多个
    query.addHighlightField("content");
    query.addHighlightField("title");
    //设置前缀后缀
    query.setHighlightSimplePre("");
    query.setHighlightSimplePost("");
    //设置高亮分片,默认是1
    query.setHighlightSnippets(1);

    //高亮之前的结果
    QueryResponse response = solrServer.query(query);
    List documents = response.getBeans(SolrDocument.class);
    for (SolrDocument document : documents) {
        System.out.println(document);
    }

    //高亮之后的结果
    Map>> highlighting =
            response.getHighlighting();
    for (String docId : highlighting.keySet()) {
        System.out.println("Document ID : " + docId);
        Map> stringListMap = highlighting.get(docId);
        for (String field : stringListMap.keySet()) {
            System.out.println("Document field" + field);
            List stringList = stringListMap.get(field);
            System.out.println("高亮之后 : " + stringList);
        }
    }
}

Solr 中的注意事项

  • schema.xml 中的 Field 如果定义为 multiValued=”true”,那么JavaBean中相应的字段必须为 List,否则可能出现添加到索引库是成功的,但是查询时异常
  • schema.xml 中只要定义了多个复制域 copyField,那么对应的JavaBean中的字段必须是 List,否则可能出现添加到索引库是成功的,但是查询时异常
  • schema.xml 中如果只有一个 copyField 复制域指向一个 Field,那么该Field的 multiValued 可以为 false,也可以为 true,如果有多个 copyField 复制域指向一个 Field,那么该 Field 的 multiValued 必须为 true,否则报错
  • 只要Field的 multiValued 为 true,那么JavaBean中对应的字段必须为 List
  • Field的 multiValued 为 false 时,JavaBean中对应的字段可以为 List,但是 List 中只能有一个元素,否则超出一个元素,执行添加操作时异常
  • schema.xml 中没有定义的 Field 在 JavaBean 中不能用 @Field 标注,否则只要在添加前,执行了 JavaBean 的 setXXX 对该 Field 赋值,就回异常
  • 如果有多个 copyField 复制域指向一个 Field,并且该 Field 是为了查询使用,那么该 Field 必须开启 indexed=”true”,例如:
<field name="text" type="text_ws" indexed="true" stored="true" multiValued="true"/>
<copyField source="title" dest="text"/>
<copyField source="content" dest="text"/>

Solr-Spring 整合

1 引入依赖

    <dependency>
        <groupId>org.springframework.datagroupId>
        <artifactId>spring-data-solrartifactId>
        <version>1.5.5.RELEASEversion>
    dependency> 

2 创建spring-solr.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:solr="http://www.springframework.org/schema/data/solr"
       xsi:schemaLocation="
           http://www.springframework.org/schema/data/solr
           http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    
    
    
    <solr:solr-server id="solrServer"
                      url="http://192.168.211.133:8080/solr/collection1" />
    
    <bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
        <constructor-arg ref="solrServer" />
    bean>
beans>

3 Field注解

public class TbItem implements Serializable{

    @Field
    private Long id;

    @Field("item_title")
    private String title;

    @Field("item_price")
    private BigDecimal price;

    @Field("item_image")
    private String image;

    @Field("item_goodsid")
    private Long goodsId;

    @Field("item_category")
    private String category;

    @Field("item_brand")
    private String brand;

    @Field("item_seller")
    private String seller;

    //动态域
    @Dynamic
    @Field("item_spec_*")
    private Map specMap;

    //get set...
}

4 schema.xml

    <fieldType name="text_ik" class="solr.TextField">
        <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
    fieldType>
    <field name="id" type="string" 
        indexed="true" stored="true" required="true" multiValued="false" /> 
    <field name="item_goodsid" type="long" indexed="true" stored="true"/>
    <field name="item_title" type="text_ik" indexed="true" stored="true"/>
    <field name="item_price" type="double" indexed="true" stored="true"/>
    <field name="item_image" type="string" indexed="false" stored="true" />
    <field name="item_category" type="string" indexed="true" stored="true" />
    <field name="item_seller" type="text_ik" indexed="true" stored="true" />
    <field name="item_brand" type="string" indexed="true" stored="true" />

    
    <field name="item_keywords" type="text_ik" 
        indexed="true" stored="false" multiValued="true"/>
    
    <copyField source="item_title" dest="item_keywords"/>
    <copyField source="item_category" dest="item_keywords"/>
    <copyField source="item_seller" dest="item_keywords"/>
    <copyField source="item_brand" dest="item_keywords"/>
    
    <dynamicField name="item_spec_*" type="string" 
        indexed="true" stored="true" />

Solr-Spring 入门案例

新增

    @Autowired
    private SolrTemplate solrTemplate;

    @Test
    public void testAdd(){
        TbItem item=new TbItem();
        item.setId(1L);
        item.setBrand("华为");
        item.setCategory("手机");
        item.setGoodsId(1L);
        item.setSeller("华为2号专卖店");
        item.setTitle("华为Mate9");
        item.setPrice(new BigDecimal(2000));        
        solrTemplate.saveBean(item);
        solrTemplate.commit();
    }

新增集合

@Test
public void testAddList(){
    List list=new ArrayList();

    for(int i=0;i<100;i++){
        TbItem item=new TbItem();
        item.setId(i+1L);
        item.setBrand("华为");
        item.setCategory("手机");
        item.setGoodsId(1L);
        item.setSeller("华为2号专卖店");
        item.setTitle("华为Mate"+i);
        item.setPrice(new BigDecimal(2000+i));  
        list.add(item);
    }

    solrTemplate.saveBeans(list);
    solrTemplate.commit();
}

查询

@Test
public void testFindOne(){
    TbItem item = solrTemplate.getById(1, TbItem.class);
    System.out.println(item.getTitle());
}

分页查询

@Test
public void testPageQuery(){
    Query query=new SimpleQuery("*:*");
    query.setOffset(20);//开始索引(默认0)
    query.setRows(20);//每页记录数(默认10)
    ScoredPage page = solrTemplate.queryForPage(query, TbItem.class);
    System.out.println("总记录数:"+page.getTotalElements());
    List list = page.getContent();
    showList(list);
}   
//显示记录数据
private void showList(List list){       
    for(TbItem item:list){
        System.out.println(item.getTitle() +item.getPrice());
    }       
}

条件查询

注 : 注意条件查询时一定要用criteria重新接收一次值的引用

@Test
public void testPageQueryMutil(){   
    Query query=new SimpleQuery("*:*");
    Criteria criteria=new Criteria("item_title").contains("2");
    //注意下面这里一定要用criteria重新接收一次值的引用
    //否则下面这个条件不会生效
    criteria=criteria.and("item_title").contains("5");      
    query.addCriteria(criteria);
    //query.setOffset(20);//开始索引(默认0)
    //query.setRows(20);//每页记录数(默认10)
    ScoredPage page = solrTemplate.queryForPage(query, TbItem.class);
    System.out.println("总记录数:"+page.getTotalElements());
    List list = page.getContent();
    showList(list);
}

删除全部数据

@Test
public void testDeleteAll(){
    Query query=new SimpleQuery("*:*");
    solrTemplate.delete(query);
    solrTemplate.commit();
}

分组查询

    @Autowired
    private SolrTemplate solrTemplate;

    //将查询出来的结果按照 item_category 字段进行分组
    private List<String> searchCategroyByKeyWords(Map map) {
        List<String> result = new ArrayList<>();

        Query query = new SimpleQuery();
        //设置条件
        Criteria criteria = new Criteria("item_keywords").is(map.get("keywords"));
        query.addCriteria(criteria);
        //设置分组
        GroupOptions groupOptions = new GroupOptions().addGroupByField("item_category");
        query.setGroupOptions(groupOptions);
        GroupPage<TbItem> groupPage = solrTemplate.queryForGroupPage(query, TbItem.class);
        //获取结果集
        GroupResult<TbItem> groupResult = groupPage.getGroupResult("item_category");
        Page<GroupEntry<TbItem>> groupEntries = groupResult.getGroupEntries();
        List<GroupEntry<TbItem>> content = groupEntries.getContent();
        for (GroupEntry<TbItem> tbItemGroupEntry : content) {
            result.add(tbItemGroupEntry.getGroupValue());
        }
        return result;
    }

多字段分组查询

    //将查询出来的结果分别按照 item_category、item_brand 字段进行分组
    private List searchCategroyByKeyWords(Map map) {
        List result = new ArrayList<>();
        List categoryList = new ArrayList<>();
        List brandList = new ArrayList<>();
        Query query = new SimpleQuery();
        //设置条件
        Criteria criteria = new Criteria("item_keywords").is(map.get("keywords"));
        query.addCriteria(criteria);
        //设置分组
        GroupOptions groupOptions = new GroupOptions()
                .addGroupByField("item_category").addGroupByField("item_brand");
        query.setGroupOptions(groupOptions);
        GroupPage groupPage = solrTemplate.queryForGroupPage(query, TbItem.class);
        //获取 item_category 分组结果集
        GroupResult groupResult = groupPage.getGroupResult("item_category");
        Page> groupEntries = groupResult.getGroupEntries();
        List> content = groupEntries.getContent();
        for (GroupEntry tbItemGroupEntry : content) {
            result.add(tbItemGroupEntry.getGroupValue());
            categoryList.add(tbItemGroupEntry.getGroupValue());
        }
        //获取 item_brand 分组结果集
        groupResult = groupPage.getGroupResult("item_brand");
        groupEntries = groupResult.getGroupEntries();
        content = groupEntries.getContent();
        for (GroupEntry tbItemGroupEntry : content) {
            result.add(tbItemGroupEntry.getGroupValue());
            brandList.add(tbItemGroupEntry.getGroupValue());
        }
        System.out.println("categoryList"+categoryList);
        System.out.println("brandList"+brandList);
        System.out.println("result"+result);
        /*
         categoryList[手机, 平板电视, 内存, 电子书]
         brandList[三星, 联想, 酷派]
         result[手机, 平板电视, 内存, 电子书, 三星, 联想, 酷派]
         */
        return result;
    }

综合运用 : 高亮、Filter过滤查询、分页、排序

    /**
     * 设置高亮、Filter过滤查询、分页、排序
     * @param map
     * @return
     */
    private Map hightSearch(Map map) {
        Map result = new HashMap();
        HighlightQuery query = new SimpleHighlightQuery();

        //设置高亮
        HighlightOptions highlightOptions = new HighlightOptions();
        highlightOptions.addField("item_title");
        highlightOptions.setSimplePrefix("");
        highlightOptions.setSimplePostfix("");
        query.setHighlightOptions(highlightOptions);

        //查询条件
        String keywords = (String) map.get("keywords");
        Criteria criteria = new Criteria("item_title").is(keywords.replace(" ",""));
        query.addCriteria(criteria);

        //过滤条件
        if (map.get("category") != null && !map.get("category").equals("")) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            filterQuery.addCriteria(
                    new Criteria("item_category").is(map.get("category")));
            query.addFilterQuery(filterQuery);
        }
        if (map.get("brand") != null && !map.get("brand").equals("")) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            filterQuery.
                    addCriteria(new Criteria("item_brand").is(map.get("brand")));
            query.addFilterQuery(filterQuery);
        }
        Map spec = (Map) map.get("spec");
        if (spec != null && spec.size() > 0) {
            for (String key : spec.keySet()) {
                String value = spec.get(key);
                FilterQuery filterQuery = new SimpleFilterQuery();
                filterQuery.addCriteria(new Criteria("item_spec_" + key).is(value));
                query.addFilterQuery(filterQuery);
            }
        }

        //价格过滤
        String price = (String) map.get("price");
        if (price != null && !"".equals(price.trim())) {
            String[] split = price.split("-");
            if ( split.length == 1 ) {
                FilterQuery filterQuery = new SimpleFilterQuery();
                Criteria criteriaPrice = 
                        new Criteria("item_price").greaterThanEqual(split[0]);
                filterQuery.addCriteria(criteriaPrice);
                query.addFilterQuery(filterQuery);
            } else if ( split.length == 2 ){
                FilterQuery filterQuery = new SimpleFilterQuery();
                Criteria criteriaPrice = 
                        new Criteria("item_price").greaterThanEqual(split[0]);
                criteriaPrice = 
                        criteriaPrice.and("item_price").lessThanEqual(split[1]);
                filterQuery.addCriteria(criteriaPrice);
                query.addFilterQuery(filterQuery);
            }
        }

        //分页
        Integer pageNum = (Integer) map.get("pageNum");
        Integer pageSize = (Integer) map.get("pageSize");
        if ( pageNum == null ) {
            pageNum = 1;
        }
        if ( pageSize == null ) {
            pageSize = 10;
        }
        query.setOffset((pageNum-1)*pageSize);
        query.setRows(pageSize);

        //排序
        String sortField = (String) map.get("sortField");
        String sortStr = (String) map.get("sort");
        if (StringUtils.isNotEmpty(sortField)&&StringUtils.isNotEmpty(sortStr)) {
            if (sortStr.equals("ASC")) {
                Sort sort = new Sort(Sort.Direction.ASC,"item_"+sortField);
                query.addSort(sort);
            }
            if (sortStr.equals("DESC")) {
                Sort sort = new Sort(Sort.Direction.DESC,"item_"+sortField);
                query.addSort(sort);
            }
        }

        HighlightPage highlightPage =
                solrTemplate.queryForHighlightPage(query, TbItem.class);

        //遍历高亮结果
        List> highlighted = highlightPage.getHighlighted();
        if (highlighted != null && highlighted.size() > 0) {
            for (HighlightEntry tbItemHighlightEntry : highlighted) {
                TbItem tbItem = tbItemHighlightEntry.getEntity();
                List highlights = 
                        tbItemHighlightEntry.getHighlights();
                if (highlights != null && highlights.size() > 0) {
                    for (HighlightEntry.Highlight highlight : highlights) {
                        //获取分片结果集
                        List snipplets = highlight.getSnipplets();
                        String title = snipplets.get(0);
                        tbItem.setTitle(title);
                    }
                }
            }
        }

        List tbItems = highlightPage.getContent();
        //总记录数
        long totalElements = highlightPage.getTotalElements();
        //总页数
        int totalPages = highlightPage.getTotalPages();
        result.put("totals", totalElements);
        result.put("totalPages", totalPages);
        result.put("rows", tbItems);
        return result;
    }

至此,关于 Solr 在Java中的使用就介绍完啦~

你可能感兴趣的:(搜索引擎)