• 利用java反射机制编写solr通用的java客户端


    一、前言

      通过上一篇的讲解,我们知道了dynamicFiled字段,它是动态的,不需要显示的声明。而且一些常用的基本类型solr已经默认给我们创建好了。

      例如:*_i,*_is,等。

      如果我们要使用动态字段,字段的命名就需要符合上述规则。solr为我们提供了大量的动态字段:

      

    二、实体类的编写

      在这里,我们以创建商品的索引为例,创建实体如下:

    @Getter@Setter
    public class Product {
      //商品id,而且是必有字段
    private String id;
    //商品名称,是字符串类型,所以我们以"_s"结尾
    private String proName_s;
      //商品架构 是double型,所以以"_d"结尾
    private Double price_d;
      //商品分类 是字符串类型,而且一个商品可以有多个分类,是多值,所以我们用“_ss”结尾
    private List<String> tag_ss; }

    三、solrj编写java通用客户端

      我们主要是通过java的反射机制和泛型来编写:

    package com.urwork.tools.solr;
    
    import com.urwork.tools.page.Page;
    import org.apache.commons.collections.CollectionUtils;
    import org.apache.solr.client.solrj.SolrQuery;
    import org.apache.solr.client.solrj.impl.CloudSolrClient;
    import org.apache.solr.client.solrj.response.QueryResponse;
    import org.apache.solr.common.SolrDocument;
    import org.apache.solr.common.SolrDocumentList;
    import org.apache.solr.common.SolrInputDocument;
    
    import java.io.IOException;
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by xxx on xxxx/xx/xx.
     */
    public class SolrCloudClient {
        private CloudSolrClient server=null;
    
        /**
         * 构造函数
         * @param zkAddr        zk地址:192.168.2.233:2181,192.168.2.234:2181,192.168.2.235:2181
         * @param collection    collection名字: company
         */
        private SolrCloudClient(String zkAddr,String collection) {
            server = new CloudSolrClient.Builder().withZkHost(zkAddr).build();
            server.setDefaultCollection(collection);
        }
    
        /**
         * 删除集合中的所有数据
         * @throws Exception
         */
        public void deleteAll() throws Exception {
            server.deleteByQuery("*:*");
            server.commit();
        }
    
        /**
         * 根据id删除集合中的数据
         * @param id
         * @throws Exception
         */
        public void deleteById(String id) throws Exception {
            server.deleteById(id);
            server.commit();
        }
    
        /**
         * 根据ids删除集合中的数据
         * @param ids
         * @throws Exception
         */
        public void deleteByIds(List<String> ids) throws Exception {
            server.deleteById(ids);
            server.commit();
        }
    
        /**
         * 批量更新索引
         * @param docs
         * @param <T>
         * @throws Exception
         */
        public <T> void addList(List<T> docs) throws Exception {
            if (CollectionUtils.isEmpty(docs)){
                return;
            }
            List<SolrInputDocument> list = new ArrayList<>();
            for (T doc:docs){
                Field[] declaredFields = doc.getClass().getDeclaredFields();
                SolrInputDocument sid = new SolrInputDocument();
                for (Field field : declaredFields){
                    field.setAccessible(true);
                    String name = field.getName();
                    Object value = field.get(doc);
                    if (value!=null){
                        sid.addField(name,value);
                    }
                    list.add(sid);
                }
            }
    
            server.add(list);
            server.commit();
        }
    
        /**
         * 添加单条索引
         * @param doc
         * @param <T>
         * @throws Exception
         */
        public <T> void add(T doc) throws Exception {
            List<T> docs = new ArrayList<>();
            docs.add(doc);
            addList(docs);
        }
    
        /**
         * 更新一条索引
         * @param doc
         * @param <T>
         * @throws Exception
         */
        public <T> void update(T doc)throws Exception{
            Field idField = doc.getClass().getDeclaredField("id");
            if (idField == null){
                throw new RuntimeException("your document doesn't have id");
            }
            idField.setAccessible(true);
            Object id = idField.get(doc);
            deleteById(id+"");
            add(doc);
        }
    
        /**
         * 批量更新索引
         * @param docs
         * @param <T>
         * @throws Exception
         */
        public <T> void updateList(List<T> docs) throws Exception {
            if (CollectionUtils.isEmpty(docs)){
                return;
            }
            List<String> ids = new ArrayList<>();
            for (T doc : docs){
                Field idField = doc.getClass().getDeclaredField("id");
                if (idField!=null){
                    idField.setAccessible(true);
                    Object id = idField.get(doc);
                    ids.add(id+"");
                }
            }
            deleteByIds(ids);
            addList(docs);
        }
    
        /**
         * 执行查询
         * @param clazz      对应的class
         * @param page       Page分页
         * @param query      查询条件
         * @param <T>
         * @return
         * @throws Exception
         */
        public <T> Page<T> search(Class<T> clazz,Page<T> page, SolrQuery query) throws Exception {
            query.setStart((page.getCurrentPageNo()-1)*page.getPageSize());
            query.setRows(page.getPageSize());
    
            QueryResponse response = server.query(query);
            SolrDocumentList results = response.getResults();
            List<T> rtnList = new ArrayList<>();
            for (SolrDocument doc : results){
                T instance = clazz.newInstance();
                Field[] declaredFields = instance.getClass().getDeclaredFields();
                for (Field filed : declaredFields){
                    filed.setAccessible(true);
                    String name = filed.getName();
                    Object fieldValue =doc.getFieldValue(name);
                    filed.set(instance,fieldValue);
                }
                rtnList.add(instance);
            }
            page.setResult(rtnList);
            page.setTotalRecord((int)results.getNumFound());
            return page;
        }
    
        public void close() throws IOException {
            server.close();
        }
    
    }

      我们在创建实体类时,字段的名称按照动态值的规则命名,在构建索引和查询时,就可以使用公共类来实现。

      

  • 相关阅读:
    poj3614 Sunscreen 题解报告
    poj2299 Ultra-QuickSort 题解报告
    poj3784 Running Median 题解报告(对顶堆)
    CH103 Cinema 题解报告
    poj1845 Sumdiv 题解报告
    poj2018 Best Cow Fences 题解报告
    $CF311B Cats Transport$ 斜率优化
    斜率优化入门题:任务安排$123$ : )
    $Poj1821 Fence $单调队列优化$DP$
    《算法竞赛》$0×00$基本算法
  • 原文地址:https://www.cnblogs.com/boboooo/p/7111729.html
Copyright © 2020-2023  润新知