Skip to content

以前的部署日志

初始化

通过docker 部署及创建登录用户

sh
# 通过docker部署solr并创建登录用户,同时挂载卷用于映射本地文件夹到容器内部
docker run --name solr -p 8983:8983 -d --restart=always -v /data/solr/custom-lib:/opt/solr-8.4.1/server/solr-webapp/webapp/WEB-INF/lib -v /data/solr/conf:/var/solr/data/problem/conf -v /data/solr/classes:/opt/solr-8.4.1/server/solr-webapp/webapp/WEB-INF/classes solr
docker exec -it --user=solr solr bin/solr create_core -c problem

ik分词器

IK Analyzer Solr的Maven仓库地址 下载jar包,放置到本地/data/solr/custom-lib目录下,容器会自动映射,无需手动拷贝。同样将ik配置文件放置到本地/data/solr/classes目录下,容器也会自动映射。

修改managed-schema文件,直接在本地/data/solr/conf目录下进行编辑,编辑完成后容器会自动更新,内容如下:

xml
#文件最下加入….
<fieldType name="text_ik" class="solr.TextField">		
    <analyzer type="index">		
        <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" />		
        <filter class="solr.LowerCaseFilterFactory"/>			
    </analyzer>		
    <analyzer type="query">		
        <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="true" />	
        <filter class="solr.LowerCaseFilterFactory"/>	
    </analyzer>			
</fieldType>

配置solr登录密码

在容器内部进行配置:

sh
docker exec -it --user root solr  /bin/bash
cd /opt/solr/server/etc
vi verify.properties 
#写入
#用户名 密码 权限
#iksolr:ik3423,admin

# 生成加密的密码
java -cp /opt/solr-8.4.1/server/lib/jetty-util-9.4.19.v20190610.jar org.eclipse.jetty.util.security.Password iksolr ik3423

# 得到加密后的应该为
# 用户名 密码 权限
# iksolr:MD5:87a3ed00e309efd07a5f9c2629ebdf22,admin

对solr-jetty-context.xml文件进行配置:

sh
docker cp solr:/opt/solr/server/contexts/ solr-jetty-context.xml /data/solr
xml
<Get name="securityHandler">    
         <Set name="loginService">    
                 <New class="org.eclipse.jetty.security.HashLoginService">    
                        <Set name="name">verify—name</Set> 
                        <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/verify.properties</Set>    
                 </New>    
         </Set>    
</Get>

最后,将修改后的文件拷贝回容器:

sh
docker cp /data/solr/solr-jetty-context.xml solr:/opt/solr/server/contexts
docker cp solr:/opt/solr-8.4.1/server/solr-webapp/webapp/WEB-INF/web.xml /data/solr

注释web.xml中的security-constraint部分。

java 使用

java
/**
 * @author hjh
 * @version 1.0
 * @date 2020/2/17 15:28
 */
@Component
public class SolrSevcie {

    @Autowired
    private HttpSolrClient client;

    /**
     * 添加或更新
     *
     * @param bean
     */
    public <T> boolean save(T bean) throws Exception {
        SolrInputDocument document = new SolrInputDocument();

        Class cla = bean.getClass();
        Field[] fields = cla.getDeclaredFields();
        for (Field field : fields) {
            //获取属性的名字
            String name = field.getName();
            //将属性的首字符大写,方便构造get,set方法
            name = name.substring(0, 1).toUpperCase() + name.substring(1);
            Method m = cla.getMethod("get" + name);
            String value = (String) m.invoke(bean);
            document.addField(field.getName(), value);
        }
        client.add(document);
        UpdateResponse result = client.commit();
        return result.getStatus() == 0;
    }

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

    /**
     * 封装过的搜索
     *
     * @param searchStr 要搜索的内容
     * @param page      开始页数
     * @param limit     每页显示条数
     * @return
     */
    public PageBean<List<SolrBean>> querySimple(String searchStr, int page, int limit) {
        return this.query("item_title:" + searchStr, (page - 1) * limit, limit, SolrBean.class);
    }

    /**
     * 封装过的搜索
     *
     * @param searchStr 要搜索的内容
     * @param page      开始页数
     * @param limit     每页显示条数
     * @return
     */
    public PageBean<List<SolrBean>> queryHighlightSimple(String searchStr, int page, int limit) {
        return this.baseQuery("item_title:" + searchStr, (page - 1) * limit, limit, "item_title", SolrBean.class);
    }

    /**
     * 调用solr搜索(普通搜索)
     *
     * @param keywords
     * @param start    从哪行开始
     * @param limit    每页显示条数
     * @param cla
     * @param <T>
     * @return
     */
    protected <T> PageBean<List<T>> query(String keywords, int start, int limit, Class<T> cla) {
        return this.baseQuery(keywords, start, limit, null, cla);
    }

    /**
     * 自动提示
     * @param value
     * @return
     */
    public PageBean<List<SolrBean>> term(String value) {
        List<String> str = this.term("item_title", value);
        if (Is.isNoEmpty(str)) {
            List<SolrBean> list = new ArrayList<>();
            str.forEach(p -> {
                SolrBean solrBean = new SolrBean();
                solrBean.setItem_title(p);
                list.add(solrBean);
            });
            PageBean pageBean = new PageBean();
            pageBean.setTotal(Long.valueOf(list.size()));
            pageBean.setRows(list);
            return pageBean;
        }
        return null;
    }

    /**
     * 自动提示
     * @param termField
     * @param value
     * @return
     */
    private List<String> term(String termField, String value) {
        SolrQuery query = new SolrQuery();
        // 不要结果集!!!
        query.setStart(0);
        query.setRows(0);
        // 该字段已在sole配置
        query.setQuery(termField + ":" + value);
        // 提词
        query.setTerms(true);
        // 最多返回10条
        query.setTermsLimit(10);
        // 可选的. 设置最小统计个数
        query.setTermsMinCount(1);
//        query.setTermsMaxCount(10);
//        query.setTermsRaw(true);
        // 可选的. 这个term开始。如果不指定,使用空字符串,这意味着从头开始的。
        // 效率更高!!!
        query.setTermsLower(value);
        // 可选的. 限制匹配,设置terms前缀是以什么开始的。
        query.setTermsPrefix(value);
        // 词频最高排序
        query.setTermsSortString("count");
        query.addTermsField(termField);
        try {
            QueryResponse result = client.query(query);
            if (result.getStatus() == 0) {
                TermsResponse termsResponse = result.getTermsResponse();
                Map<String, List<TermsResponse.Term>> map = termsResponse.getTermMap();
                List<TermsResponse.Term> list = map.get(termField);
                if (Is.isNoEmpty(list)) {
                    ArrayList<String> strs = new ArrayList<>();
                    list.forEach(l -> {
                        strs.add(l.getTerm());
                    });
                    return strs;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 调用solr搜索
     *
     * @param keywords
     * @param start
     * @param limit
     * @param hlField
     * @param cla
     * @param <T>
     * @return
     */
    private <T> PageBean<List<T>> baseQuery(String keywords, int start, int limit, String hlField, Class<T> cla) {
        SolrQuery query = new SolrQuery();
        query.setStart(start);
        query.setRows(limit);
        // 该字段已在sole配置
        query.setQuery(keywords);
        query.addSort("score", SolrQuery.ORDER.desc);
        query.setParam("q.op", "and");
        // 高亮
        boolean hlFlag = Is.isNoEmpty(hlField);
        if (hlFlag) {
            // 开启高亮
            query.setHighlight(true);
            // 高亮字段
            query.addHighlightField(hlField);
            // 高亮单词的前缀
            query.setHighlightSimplePre("<font style='color:red'>");
            // 高亮单词的后缀
            query.setHighlightSimplePost("</font>");
            //摘要最长1000个字符
            query.setHighlightFragsize(500);
            query.setSort("item_type", SolrQuery.ORDER.desc);
        }
        try {
            QueryResponse result = client.query(query);
            if (result.getStatus() == 0) {
                //[5]遍历结果
//                TermsResponse termsResponse = result.getTermsResponse();
//                List<TermsResponse.Term> terms = termsResponse.getTerms("p_name");
//                for (TermsResponse.Term term : terms) {
//                    System.out.println(term.getTerm() + ":\t"+ term.getFrequency());
//                }
                SolrDocumentList list = result.getResults();
                // 总条数
                Long total = list.getNumFound();
                List<T> tList = new ArrayList<>();
                for (SolrDocument p : list) {
                    try {
                        T t = cla.newInstance();
                        Collection<String> collection = p.getFieldNames();
                        for (String c : collection) {
                            // 判断有没有这个属性
                            if (!"_version_".equals(c) && cla.getDeclaredField(c) != null) {
                                //将属性的首字符大写,方便构造get,set方法
                                String name = c.substring(0, 1).toUpperCase() + c.substring(1);
                                System.out.print("set" + name);
                                Method m = cla.getMethod("set" + name, new Class[]{String.class});
                                m.invoke(t, (String) p.get(c));
                            }
                        }
                        if (hlFlag) {
                            //获取高亮字段name相应结果
                            NamedList<Object> response = result.getResponse();
                            //获取高亮字段name相应结果
                            NamedList<SimpleOrderedMap> highlighting = (NamedList<SimpleOrderedMap>) response.get("highlighting");
                            // 循环结果集,判断id
                            for (int i = 0; i < highlighting.size(); i++) {
                                String id = (String) cla.getMethod("getId").invoke(t);
                                // 判断id相等
                                if (highlighting.getName(i).equals(id)) {
                                    SimpleOrderedMap map = highlighting.getVal(i);
                                    ArrayList temp = (ArrayList) map.get(hlField);
                                    if (Is.isNoEmpty(temp)) {
                                        // 替换字符串
                                        String val = (String) temp.get(0);
                                        String name = hlField.substring(0, 1).toUpperCase() + hlField.substring(1);
                                        cla.getMethod("set" + name, new Class[]{String.class}).invoke(t, val);
                                    }
                                    break;
                                }
                            }
                        }
                        tList.add(t);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                PageBean pageBean = new PageBean();
                pageBean.setTotal(total);
                pageBean.setRows(tList);
                return pageBean;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
java
package com.ciw.main.solr;

import lombok.Data;

/**
 * solrj操作对象, 需先在solr里面配置对应的字段
 * @author hjh
 * @version 1.0
 * @date 2020/2/17 15:14
 */
@Data
public class SolrBean {

    /**
     * 唯一标识
     */
    private String id;

    /**
     * 要搜索的内容
     */
    private String item_title;

    /**
     * 用于区分是搜索什么
     */
    private String item_type;

    /**
     * 需要使用到的json数据
     */
    private String item_data;

}
java
/**
 * @author hjh
 * @version 1.0
 * @date 2020/2/16 19:00
 */
@Configuration
public class SolrConfig {

    @Value("${spring.data.solr.url:}")
    private String url;

    @Value("${spring.data.solr.host:}")
    private String host;

    @Value("${spring.data.solr.port:}")
    private Integer port;

    @Value("${spring.data.solr.user:}")
    private String user;

    @Value("${spring.data.solr.pwd:}")
    private String pwd;

    public class SolrAuthInterceptor implements HttpRequestInterceptor {
        @Override
        public void process(final HttpRequest request, final HttpContext context) {
            AuthState authState = (AuthState) context.getAttribute(HttpClientContext.TARGET_AUTH_STATE);
            if (authState.getAuthScheme() == null) {
                CredentialsProvider credsProvider =
                        (CredentialsProvider) context.getAttribute(HttpClientContext.CREDS_PROVIDER);
                HttpHost targetHost = (HttpHost) context.getAttribute(HttpCoreContext.HTTP_TARGET_HOST);
                AuthScope authScope = new AuthScope(targetHost.getHostName(), targetHost.getPort());
                Credentials creds = credsProvider.getCredentials(authScope);
                authState.update(new BasicScheme(), creds);
            }
        }
    }

    @Bean
    public HttpSolrClient solrClient() {
        CredentialsProvider provider = new BasicCredentialsProvider();
        provider.setCredentials(new AuthScope(host, port),
                new UsernamePasswordCredentials(user, pwd));

        HttpClientBuilder builder = HttpClientBuilder.create();
        // 请注意下面这一行,指定拦截器,用于设置认证信息
        builder.addInterceptorFirst(new SolrAuthInterceptor());
        builder.setDefaultCredentialsProvider(provider);
        CloseableHttpClient httpClient = builder.build();
        return new HttpSolrClient.Builder(url + "/problem").withHttpClient(httpClient).build();
    }
}
xml
<dependency>
    <groupId>solr</groupId>
    <artifactId>solr</artifactId>
    <version>8.4.1</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/src/main/resources/lib/solr-solrj-8.4.1.jar</systemPath>
</dependency>

粤ICP备20009776号