Solr经常出现问题

Solr服务异常

删除new_core目录下data目录下的所有数据;如果数据域类型错误,通过Solr控制台删除所有自定义数据类型并重新定义

高亮显示

高亮显示的字段修改为text_general类型,Solr中已有的数据必须重新删除并导入,Controller中定义查询条件不能包含*,比如查询: name:七匹狼

删除Solr中的文档

向Solr中添加文档时,Map中必须包含id,如果Map中没有定义id键,Solr创建文档时会自动创建id,是字符串类型,如果出现此类情形,SolrUtil删除文档方法不能成功执行

Date数据类型

实体类中设置日期数据类型时,使用java.sql.Date,Solr端对应的数据类型是pdates;
如果实体类中使用字符串类型代替日期类型,从Solr中检索出的日期数据形如:Sat Sep 15 09:30:07 CST 2018,正确显示在列表中需要按照如下处理,修改实体类中对应属性的Get方法
Public String getDt()
{
Try
{
Return new java.sql.Date(new java.util.Date(dt)).toString();
}
Catch(Exception e)
{
Return dt;
}
}
实体类使用java.sql.Date类型,Solr使用pdates类型
实例类使用String代表Date类型,Solr使用pdates类型
实体类日期字段Get方法添加如下格式转化

实体类使用String代表Date类型,Solr使用text_general类型
不需要任何转换

实体类设计规范

实体类上都需要定义id实例变量,对应数据库中的主键,关联表实体类类除外。向Solr中添加数据使用Map,所以实体类中没有必要定义注解org.apache.solr.client.solrj.beans.Field,向Solr中添加的Map必须包含id键,否则Solr会为文档自动生成id数据域,这样无法与数据库主键对应。

Map存在Null问题

SolrUtil工具类向Solr中添加文档时判断Map中值是否为空,Solr相关的错误可以避免,但如果Solr中的数据缺少某些字段值,查询列表时显示Null值,所以必须保证所有需要显示的字段都保存到Solr中。

Solr查询问题

查询字符串中不用带*,否则查询结果可能存在问题,查询数据域字段类型设置为text_general即可,不要设置为text_cn。

Solr数据类型问题

如果Solr中已经存在一些数据,比如数据域name字段类型为text_cn的字段,现在修改name的类型为text_general,新建增加的数据name的类型为text_general,原来的数据中name数据类型还是text_cn,为避免查询导致问题,需要将Solr中原来的数据清空重新导入或新建。

编译Maven项目

执行
编译:mvn compile
封装Jar: mvn jar:jar
封装war: mvn war:war
安装到本地Maven仓库 mvn install

这里写图片描述
这里写图片描述

SolrUtil工具类

package com.test.util;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;

public class SolrUtil {
    private HttpSolrClient client = null;

    public SolrUtil(String url)
    {
        //SolrJ-7.3.1
        //client = new HttpSolrClient.Builder(url).build();
        //SolrJ-5.5.5
        client = new HttpSolrClient(url);
    }

    /**
     * 将Map对象添加到Solr中
     * @param m
     */
    public boolean addMap(Map m)
    {
        //Key-Value,
        //Key Set;Value Collection
        Set kset = m.keySet();
        SolrInputDocument doc = new SolrInputDocument();
        for(Object k:kset)
        {
            Object val = m.get(k);
            if(val != null)
                doc.addField(k.toString(), val);
        }
        try
        {
            client.add(doc);
            UpdateResponse resp = client.commit();
            if(resp.getStatus() == 0)
                return true;
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 更新Solr中的文档,Map对象中必须存在id键用于定位doc文档
     * Map中其他的键值对是修改的内容,Key<String>代表数据域名称,
     * Value<Object>代表修改值
     * @param map
     */
    public boolean update(Map<String,Object> map)
    {
        try
        {
            String id = (String)map.get("id");
            SolrInputDocument doc = new SolrInputDocument();
            doc.addField("id", id);
            for(String k:map.keySet())
            {
                if(!"id".equals(k))
                {
                    Map map2 = new HashMap();
                    map2.put("set", map.get(k));
                    doc.addField(k, map2);
                }
            }
            client.add(doc);
            UpdateResponse resp = client.commit();
            if(resp.getStatus() == 0)
                return true;
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 通过文档ID删除Solr中的文档
     * @param id
     */
    public boolean deleteById(String id)
    {
        try
        {
            client.deleteById(id);
            UpdateResponse resp = client.commit();
            if(resp.getStatus() == 0)
                return true;
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 通过查询删除Solr中对应的数据集合
     * @param query
     */
    public boolean deleteByQuery(String query)
    {
        try
        {
            client.deleteByQuery(query);
            UpdateResponse resp = client.commit();
            if(resp.getStatus() == 0)
                return true;
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 通过泛型获取Solr中的对象集合
     * @param clz 泛型类对应java.lang.Class
     * @param query 数据域名称:数据域的值;查询全部*:*;多条件查询 name:Java AND age:20
     * @param flList 高亮显示数据域名称,是List<String>集合
     * @param page 分页查询时,开始记录数
     * @param rows 本次查询检索记录数
     * @return
     */
    public <T> ResultInfo<T> queryHL(Class<T> clz,String query,List<String> flList,
            Integer page,Integer rows)
    {
        try
        {
            //定义返回自定义数据结构对象
            ResultInfo<T> rslt = new ResultInfo<T>();
            SolrQuery q = new SolrQuery();
            q.set("q", query);
            q.set("fl","*");
            q.setHighlight(true);
            //高亮显示字段
            String hlField = "";
            for(String s:flList)
                hlField = hlField + s + ",";
            if(hlField.endsWith(","))
                hlField = hlField.substring(0,hlField.length()-1);
            q.set("hl.fl",hlField);
            //
            q.setHighlightSimplePre("<font color=\"red\">");
            q.setHighlightSimplePost("</font>");
            q.setStart(page);
            q.setRows(rows);
            QueryResponse qr = client.query(q);
            Map<String,Map<String,List<String>>> hlMap = qr.getHighlighting();
            System.out.println(hlMap);
            //Map<ID,Map<FieldName,[MultiValue]>>
            SolrDocumentList lst = qr.getResults();
            List<T> rtn = new ArrayList<T>();
            Long total = qr.getResults().getNumFound();

            for(SolrDocument doc:lst)
            {
                String id = (String)doc.getFieldValue("id");
                T t = clz.newInstance();
                //获取自定义类所有属性名称
                Field[] flds = getField(clz);
                for(Field field:flds)
                {
                    String fname = field.getName();
                    String solrFldName = getSolrFieldName(clz,field);               
                    String fObj = getSingleValue(doc.getFieldValue(solrFldName));
                    if(fObj == null)
                        continue;
                    if(field.getType() == java.sql.Date.class)
                    {
                        java.util.Date dt = new java.util.Date(fObj);
                        fObj = new java.sql.Date(dt.getTime()).toString();
                    }
                    if(field.getType() == java.sql.Timestamp.class)
                    {
                        java.util.Date dt = new java.util.Date(fObj);
                        fObj = new java.sql.Timestamp(dt.getTime()).toString();
                    }
                    if(field.getType() == java.sql.Time.class)
                    {
                        java.util.Date dt = new java.util.Date(fObj);
                        fObj = new java.sql.Time(dt.getTime()).toString();
                    }
                    //高亮显示数据形式
                    ////Map<ID,Map<FieldName,[MultiValue]>>
                    if(flList.contains(fname))
                    {
                        //Map<FieldName,List<MultiValue>>
                        Map<String,List<String>> fldMap = hlMap.get(id);
                        Object hlObj = fldMap.get(fname);
                        String hlVal = getSingleValue(hlObj);
                        if(hlVal != null)
                            fObj = hlVal;

                    }
                    if(fObj != null)
                        BeanUtils.setProperty(t, fname, fObj);
                }
                rtn.add(t);
            }
            rslt.setList(rtn);
            rslt.setTotal(total);
            return rslt;

        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 转化多值域为单值
     * @param obj
     * @return
     */
    private String getSingleValue(Object obj)
    {
        if(obj == null)
            return null;
        String val = obj.toString();
        if(val.startsWith("[") && val.endsWith("]"))
        {
            return val.substring(1,val.length()-1);
        }
        return val;
    }

    /**
     * 根据Class对象获取此类型的定义属性数据
     * @param clz
     * @return
     */
    private Field[] getField(Class clz)
    {
        Field[] flds = clz.getDeclaredFields();
        return flds;
    }

    /**
     * 通过Field对象取得其上定义的注解名称
     * @param clz
     * @param fld
     * @return
     */
    private String getSolrFieldName(Class clz,Field fld)
    {
        org.apache.solr.client.solrj.beans.Field fld2 = 
                fld.getAnnotation(org.apache.solr.client.solrj.beans.Field.class);
        if(fld2 == null)
            return fld.getName();

        if(fld2.value().equals("#default"))
            return fld.getName();
        else
            return fld2.value();

    }

    public static void main(String[] args)
    {
        System.out.println(new java.util.Date());
        Map m = new HashMap();
        m.put("sid", "10");
        m.put("name","Java");
        String url = "http://localhost:8984/solr/new_core2/";
        SolrUtil solr = new SolrUtil(url);
        solr.addMap(m);

    }
}

猜你喜欢

转载自blog.csdn.net/qixiang_chen/article/details/82716461
今日推荐