Solr多线程批量更新

solr服务端安装
1、下载solr-8.0.0.zip版本:下载地址:http://archive.apache.org/dist/lucene/solr/,下载完后解压到相应目录下。
2、启动、关闭solr
在解压之后的solr目录中找到bin文件夹,进去之后右键进入Powershell输入以下命令:
启动 .\solr start
关闭 .\solr stop -all
3、创建core
在solr目录中的server\solr文件夹中创建一个core文件夹,然后把server\solr\configsets\sample_techproducts_configs下面的conf文件夹复制到刚才创建的core文件夹下面。
完成上面操作之后启动solr,启动成功之后打开浏览器进入http://localhost:8983/solr/#/地址,就可以看到solr的管理页面,点击左侧的Core Admin,在新页面的name和instanceDir输入框中分别修改为刚才创建的core文件夹名称,然后点击下面Add Core按钮即可成功创建core,创建成功之后,会在你刚才创建的core文件夹下面生成一个文件夹和一个文件,这样即表示创建成功。

删除solr数据
1)documents type 选择 XML
2)documents 输入下面语句

<delete><query>*:*</query></delete>
<commit/>

在这里插入图片描述
solr批量更新

solr支持三种类型的原子更新:

  • set - to set a field.
  • add - to add to a multi-valued field.
  • inc - to increment a field.
    其中set可以是单值的也可以是multifiled, add 针对multi-field ,inc 对应数值类型

关于更新中传入的_version_值说明:

  • version<0,如果这个文档存在,则solr会拒绝修改,如果不存在,则add这个文档
  • version=0时,如果待修改的文档存在,则修改这个文档,如果不存在。则add这个文档
  • version=1 ,如果文档存在,则update这个文档,如果不存在,则拒绝修改
  • version>1, 如果文档的_version_值和传入的version值不一样,则拒绝修改,值一样则修改。

原子更新的几点问题:
如果有字段的store=false,但是在更新的时候没有给这个字段设置值,则这个字段在更新的时候数据会被丢掉; store=true的字段则不会。
针对multi-field字段,如果store=false, 则在原子更新 使用add时也会把这个字段之前的数据丢掉。

批量更新思路:
定时任务处理,每次查询5000条数据,分10个线程跑,一个线程处理500条数据。

 private void updateSolrAttachmentName() {
 		//查询共需处理多少条数据
        int buseinssQueryCount = (int) buseinssQueryService.count();
        //每次查询5000条数据
        int toIndex = 5000;
        for(int i=0;i<buseinssQueryCount;i+=toIndex){
            if(i+toIndex>buseinssQueryCount){
                toIndex = buseinssQueryCount-i;
            }
            List<BuseinssQueryEntity> buseinssQueryList = buseinssQueryService.findAllByPage(i,i+toIndex);
            updateAttachmentName(buseinssQueryList);
        }
    }

多线程批量处理数据推送到solr

private void updateAttachmentName(List<BuseinssQueryEntity> list) {
        // 开始时间
        long start = System.currentTimeMillis();
        // 每500条数据开启一条线程
        int threadSize = 500;
        // 总数据条数
        int dataSize = list.size();
        // 线程数
        int threadNum = dataSize / threadSize + 1;
        // 定义标记,过滤threadNum为整数
        boolean special = dataSize % threadSize == 0;
        // 创建一个线程池
        ExecutorService exec = Executors.newFixedThreadPool(threadNum);
        // 定义一个任务集合
        List<Callable<List<BuseinssQueryEntity>>> tasks = new ArrayList<Callable<List<BuseinssQueryEntity>>>();
        Callable<List<BuseinssQueryEntity>> task = null;
        List<BuseinssQueryEntity> cutList = null;
        // 确定每条线程的数据
        for (int i = 0; i < threadNum; i++) {
            if (i == threadNum - 1) {
                if (special) {
                    break;
                }
                cutList = list.subList(threadSize * i, dataSize);
            } else {
                cutList = list.subList(threadSize * i, threadSize * (i + 1));
            }
            final List<BuseinssQueryEntity> listStr = cutList;
            task = new Callable<List<BuseinssQueryEntity>>() {

                @Override
                public List<BuseinssQueryEntity> call() throws Exception {
                    return listStr;
                }
            };
            // 这里提交的任务容器列表和返回的Future列表存在顺序对应的关系
            tasks.add(task);
        }
        List<Future<List<BuseinssQueryEntity>>> results;
        int sum=0;
        try {
            results = exec.invokeAll(tasks);
            for (Future<List<BuseinssQueryEntity>> future : results) {
                String url = "http://solr.hd.com:8983/solr/OA_HISTORY";
                HttpSolrClient solrClient = new HttpSolrClient.Builder().withBaseSolrUrl(url).build();
                Collection<SolrInputDocument> updateDocList = new ArrayList<>();
                for (BuseinssQueryEntity buseinssQueryEntity : future.get()) {
                    try {
                        System.out.println("历史数据id:"+buseinssQueryEntity.getId());
                        //先查询附件名称是否有值
                        SolrQuery query = new SolrQuery();
                        query.set("fl", "attachmentName");
                        query.setFields("attachmentName");
                        query.set("q", "id:OCT_BUSINESSQUERY_"+buseinssQueryEntity.getId());
                        QueryResponse response = solrClient.query(query);
                        SolrDocumentList list1 = response.getResults();
                        System.out.println(list1.size());
                        if(list1==null||list1.size()==0) {
                            continue;
                        }
                        SolrDocument solrDoc = list1.get(0);
                        Map<String, Object> mapField = solrDoc.getFieldValueMap();
                        String attachmentNameStr = (String) mapField.get("attachmentName");
                        //如果附件名称没有值则进行更新
                        if(attachmentNameStr == null || attachmentNameStr == "") {
                          //根据附件关联uuid查询附件名称
                            StringBuffer buf = new StringBuffer(""); 
                            String attachmentName = "";
                            Attachment[] attachments = attachmentService.getAttachments(buseinssQueryEntity.getAttachment(), true);
                            String pdfName = buseinssQueryEntity.getPdfPath();
                            for(Attachment attachment:attachments){  
                                if(pdfName.indexOf(attachment.getName())<0) {
                                    buf.append(attachment.getName()).append(",");
                                }
                            }
                            int count = buf.toString().indexOf(",");
                            if(count>-1){
                                attachmentName =buf.substring(0, buf.length()-1);//去掉最后一个逗号
                            }
                            //附件有值才更新
                            if(attachmentName != null && attachmentName != "") {
                                SolrInputDocument document = new SolrInputDocument();
                                document.addField("id", "OCT_BUSINESSQUERY_"+buseinssQueryEntity.getId());
                                Map<String,String> map = new HashMap<String,String>();
                                map.put("add", attachmentName);
                                document.addField("attachmentName", map);
                              
                                //version<0,如果这个文档存在,则solr会拒绝修改,如果不存在,则add这个文档
                                //version=0时,如果待修改的文档存在,则修改这个文档,如果不存在。则add这个文档
                                //version=1 ,如果文档存在,则update这个文档,如果不存在,则拒绝修改
                                //version>1, 如果文档的_version_值和传入的version值不一样,则拒绝修改,值一样则修改。
                                document.addField("_version_", 1);
                                updateDocList.add(document);
                                ++sum;
                            }
                        }
                    } catch (Exception e) {
                        BuseinessQueryLogEntity buseinessQueryLog = new BuseinessQueryLogEntity();
                        buseinessQueryLog.setSrcId(buseinssQueryEntity.getSourceId());
                        buseinessQueryLog.setSrcTitle(buseinssQueryEntity.getTitle());
                        buseinessQueryLog.setError("定时任务同步附件名称异常");
                        String result;
                        String stackTrace = PigeonholeUtils.printStackTraceToString(e);
                        String exceptionType = e.toString();
                        String exceptionMessage = e.getMessage();
                        result = String.format("%s : %s \r\n %s", exceptionType, exceptionMessage, stackTrace);
                        buseinessQueryLog.setErrorStr(result);
                        buseinessQueryLog.setOperationTime(new DateTime());
                        buseinessQueryLog.setOperationAccount("hdadmin");
                        buseinessQueryLog.setTmpId(buseinssQueryEntity.getId().toString());
                        buseinessQueryLog.setSource(buseinssQueryEntity.getSystemType());
                        buseinessQueryLog.setDeleted(0);
                        buseinessQueryLogService.merge(buseinessQueryLog);
                        e.printStackTrace();
                    }
                    System.out.println(buseinssQueryEntity.getId()+",线程:"+Thread.currentThread().getName());//推送1000条花了9分钟
                }
                if(updateDocList.size()>0) {
                    solrClient.add(updateDocList);
                    solrClient.commit();
                }
                solrClient.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        
     // 关闭线程池
        exec.shutdown();
        System.out.println("共处理"+sum+"条数据");
        System.err.println("执行任务消耗了 :" + (System.currentTimeMillis() - start) + "毫秒");
    }

solr查询某个字段

public static void main(String[] args) {
        try {
            String url = "http://solr.hd.com:8983/solr/OA_HISTORY";
            HttpSolrClient solrClient = new HttpSolrClient.Builder().withBaseSolrUrl(url).build();
            SolrQuery query = new SolrQuery();
            query.set("fl", "attachmentName");
            query.setFields("attachmentName");
            query.set("q", "id:OCT_BUSINESSQUERY_2501");
            QueryResponse response = solrClient.query(query);
            //转成对象集合
            List<BuseinssQueryEntity> list = response.getBeans(BuseinssQueryEntity.class);
            //转成SolrDocumentList
            SolrDocumentList list1 = response.getResults();
            
            SolrDocument document = list1.get(0);
            Map<String, Object> map = document.getFieldValueMap();
            String attachmentName = (String) map.get("attachmentName");
            System.out.println(attachmentName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值