Solr7.3定时与JAVA操作?

1.solr详细介绍与java操作

https://blog.csdn.net/bskfnvjtlyzmv867/article/details/80940089

Java操作SOLR很全面的文章。

2.solr管理界面定时

http://www.cnblogs.com/milude0161/p/9228547.html

暂时没有调试成功

3.quartz方式定时

        <dependency>
            <groupId>org.apache.solr</groupId>
            <artifactId>solr-solrj</artifactId>
            <version>7.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.3</version>
            <exclusions>
                <exclusion>
                    <artifactId>c3p0</artifactId>
                    <groupId>c3p0</groupId>
                </exclusion>
            </exclusions>
        </dependency>
<!-- 要调用的工作类-->
    <bean id="myproductSearchIndex" class="com.xx.xx.handler.MyproductSearchIndex"></bean>
    <bean id="jobTask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <!-- 调用的类 -->
        <property name="targetObject" ref="myproductSearchIndex"/>
        <!-- 调用类中的方法 -->
        <property name="targetMethod" value="run"/>
        <!--表示不并发操作-->
        <property name="concurrent" value="false"/>
    </bean>
    <!-- 配置定时器时间间隔 -->
    <!-- 定义时间间隔触发器  */10 * * * * ?表示每隔10秒执行一次-->
    <bean id="jobTaskTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail">
            <ref bean="jobTask" />
        </property>
        <property name="cronExpression">
            <value>0 0/30 * * * ?</value><!-- 每隔30分执行一次 -->
        </property>
    </bean>
    <!--配置启动定时器-->
    <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="applicationContextSchedulerContextKey" value="applicationContext" />
        <property name="triggers">
            <list>
                <ref bean="jobTaskTrigger" />
            </list>
        </property>
    </bean>
MyproductSearchIndex.java
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.request.QueryRequest;
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 org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.util.NamedList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Component
public class MyproductSearchIndex {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyproductSearchIndex.class);
    enum Command {
        DELTA_IMPORT, FULL_IMPORT
    }
    public void run() {
        try {
            // solr服务的url,my_core是前面创建的solr core
            String url = "http://localhost:4012/solr7/my_core";
            // 创建HttpSolrClient
            SolrClient solrClient = new HttpSolrClient.Builder(url)
                    .withConnectionTimeout(5000)
                    .withSocketTimeout(5000)
                    .build();
            SolrRequest<QueryResponse> request = buildRequest(Command.DELTA_IMPORT, "SYSROLE");
            request.setPath("/dataimport");
            NamedList<Object> resp = solrClient.request(request, null);
            LOGGER.info(" 重建索引成功,具体结果:" + resp.toString());
        } catch (Exception e) {
            LOGGER.info(" 重建索引成功,异常信息:" + e.getMessage());
            e.printStackTrace();
        }
    }

    private SolrRequest<QueryResponse> buildRequest(Command command, String entity) {
        Map<String, String> map = new HashMap<>();
        switch (command) {
            case DELTA_IMPORT:
                map.put("command", "delta-import");
                map.put("clean", "false");
                map.put("commit", "true");
                map.put("optimize", "false");
                map.put("index", "false");
                map.put("entity", entity);
                map.put("debug", "false");
                map.put("wt", "json");
                return new QueryRequest(new MapSolrParams(map));
            case FULL_IMPORT:
                map.put("command", "full-import");
                map.put("clean", "true");
                map.put("commit", "true");
                map.put("optimize", "false");
                map.put("entity", entity);
                map.put("index", "false");
                map.put("debug", "false");
                map.put("wt", "json");
                return new QueryRequest(new MapSolrParams(map));
        }
        return null;
    }

    public  void insertOrUpdateIndex() throws IOException, SolrServerException {
        // solr服务的url,my_core是前面创建的solr core
        String url = "http://localhost:4012/solr7/my_core";
        // 创建HttpSolrClient
        HttpSolrClient client = new HttpSolrClient.Builder(url)
                .withConnectionTimeout(5000)
                .withSocketTimeout(5000)
                .build();
        // 创建Document对象
        SolrInputDocument document = new SolrInputDocument();
        document.addField("id", "1111");
        document.addField("NAME", "Solr入门xxxxyy");
        document.addField("ENNAME", "Solr版本差异也太大了xxxxyy");
        document.addField("DATASCOPE", "Solr版本差异也太大了DATASCOPExxxyy");
        client.add(document);
        client.commit();
    }

    public  void deleteIndex() throws IOException, SolrServerException {
        String url = "http://localhost:4012/solr7/my_core";
        HttpSolrClient client = new HttpSolrClient.Builder(url)
                .withConnectionTimeout(5000)
                .withSocketTimeout(5000)
                .build();
        client.deleteById("1111");
        client.commit();
        // 根据条件删除
        //client.deleteByQuery("id:1111");
        // 全部删除
        //client.deleteByQuery("*:*");
    }

    public  void simpleSearch() throws IOException, SolrServerException {
        String url = "http://localhost:4012/solr7/my_core";
        HttpSolrClient client = new HttpSolrClient.Builder(url)
                .withConnectionTimeout(5000)
                .withSocketTimeout(5000)
                .build();
        // 创建SolrQuery
        SolrQuery query = new SolrQuery();
        // 输入查询条件
        query.setQuery("NAME:*x");
        query.setRows(20);
        // 执行查询并返回结果
        QueryResponse response = client.query(query);
        // 获取匹配的所有结果
        SolrDocumentList list = response.getResults();
        // 匹配结果总数
        long count = list.getNumFound();
        System.out.println("总结果数:" + count);

        for (SolrDocument document : list) {
            System.out.println(document.get("id"));
            System.out.println(document.get("NAME"));
            System.out.println(document.get("ENNAME"));
            System.out.println(document.get("DATASCOPE"));
            System.out.println("================");
        }
    }
}

 

4.crontab定时任务

crontab 为例 每隔一分钟,定时Get请求方式访问URL进行增量导入

Linux终端下输入crontab -e进入编辑模式

*/3 * * * * /usr/bin/curl 'http://10.1.xx.xx:4012/solr7/my_core/dataimport?command=delta-import&clean=false&commit=true'

保存,退出。service crond restart         //重启服务

用 ls /var/log/cron* 查看日志名称,再使用tail -f /var/log/cron-20170928查看日志

5.shell定时任务

a.编写shell脚本,在/usr/local/quarz.sh

curl 'http://10.1.xx.xx:4012/solr7/my_core/dataimport?command=delta-import&clean=false&commit=true'
echo 'solr-core:my_core delta-import success.'

b.为脚本添加可执行权限:chmod +x quarz.sh

c.通过cron在系统后台定期执行刚刚创建的脚本,执行以下命令,编辑crontab文件

终端下输入crontab -e进入编辑模式

*/1    *    *    *    *        /usr/local/quarz.sh

保存,退出。service crond restart         //重启服务

6.spring data solr操作

a.引入jar包

		<!-- solr客户端 -->
		<dependency>
			<groupId>org.apache.solr</groupId>
			<artifactId>solr-solrj</artifactId>
			<version>7.3.0</version>
		</dependency>
		<!--spring data solr-->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-solr</artifactId>
			<version>1.5.5.RELEASE</version>
		</dependency>

b.bean建立

	<bean id="solrClientFactory" class="org.springframework.data.solr.server.support.HttpSolrClientFactoryBean">
		<property name="url" value="http://10.x.xx.xx:4012/solr7/my_core"/>
		<property name="timeout" value="15000"/>
		<property name="maxConnections" value="100"/>
	</bean>
	<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
		<constructor-arg index="0" ref="solrClientFactory"/>
	</bean>

c.配置域

域相当于数据库的表字段,用户存放数据,因此用户根据业务需要去定义相关的Field(域),一般来说,每一种对应着一种数据,用户对同一种数据进行相同的操作。

域的常用属性:
• name:指定域的名称
• type:指定域的类型
• indexed:是否索引
• stored:是否存储
• required:是否必须
• multiValued:是否多值

1、域

  Solr中默认定义唯一主键key为id域,如下:<uniqueKey>id</uniqueKey>

Solr在删除、更新索引时使用id域进行判断,也可以自定义唯一主键。
  注意在创建索引时必须指定唯一约束。

<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" />

2、copyField复制域

  copyField复制域,可以将多个Field复制到一个Field中,以便进行统一的检索:
  比如,根据关键字只搜索item_keywords域的内容就相当于搜索item_title、item_category、item_seller、item_brand,即将item_title、item_category、item_seller、item_brand复制到item_keywords域中。

  目标域必须是多值的。

<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"/>

3、dynamicField(动态字段)

  动态字段就是不用指定具体的名称,只要定义字段名称的规则,例如定义一个 dynamicField,name 为*_i,定义它的type为text,那么在使用这个字段的时候,任何以_i结尾的字段都被认为是符合这个定义的,例如:name_i,gender_i,school_i等。

  自定义Field名为:product_title_t,“product_title_t”和scheam.xml中的dynamicField规则匹配成功。

  如:配置:<dynamicField name="item_spec_*" type="string" indexed="true" stored="true" />

d.建立表

CREATE TABLE `tb_item` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '商品id,同时也是商品编号',
  `title` varchar(100) NOT NULL COMMENT '商品标题',
  `sell_point` varchar(500) DEFAULT NULL COMMENT '商品卖点',
  `price` decimal(20,2) NOT NULL COMMENT '商品价格,单位为:元',
  `stock_count` int(10) DEFAULT NULL,
  `num` int(10) NOT NULL COMMENT '库存数量',
  `barcode` varchar(30) DEFAULT NULL COMMENT '商品条形码',
  `image` varchar(2000) DEFAULT NULL COMMENT '商品图片',
  `categoryId` bigint(10) NOT NULL COMMENT '所属类目,叶子类目',
  `status` varchar(1) NOT NULL COMMENT '商品状态,1-正常,2-下架,3-删除',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime NOT NULL COMMENT '更新时间',
  `item_sn` varchar(30) DEFAULT NULL,
  `cost_pirce` decimal(10,2) DEFAULT NULL,
  `market_price` decimal(10,2) DEFAULT NULL,
  `is_default` varchar(1) DEFAULT NULL,
  `goods_id` bigint(20) DEFAULT NULL,
  `seller_id` varchar(30) DEFAULT NULL,
  `cart_thumbnail` varchar(150) DEFAULT NULL,
  `category` varchar(200) DEFAULT NULL,
  `brand` varchar(100) DEFAULT NULL,
  `spec` varchar(200) DEFAULT NULL,
  `seller` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `cid` (`categoryId`),
  KEY `status` (`status`),
  KEY `updated` (`update_time`)
) ENGINE=InnoDB AUTO_INCREMENT=1369286 DEFAULT CHARSET=utf8 COMMENT='商品表'

e.实体类TbItem.java,添加solr注解,映射索引字段

public class TbItem implements Serializable {
    @Field
    private Long id;

    @Field("item_title")
    private String title;

    private String sellPoint;

    @Field("item_price")
    private BigDecimal price;

    private Integer stockCount;

    private Integer num;

    private String barcode;

    @Field("item_image")
    private String image;

    private Long categoryid;

    private String status;

    private Date createTime;

    private Date updateTime;

    private String itemSn;

    private BigDecimal costPirce;

    private BigDecimal marketPrice;

    private String isDefault;

    @Field("item_goodsid")
    private Long goodsId;

    private String sellerId;

    private String cartThumbnail;

    @Field("item_category")
    private String category;

    @Field("item_brand")
    private String brand;

    private String spec;

    @Field("item_seller")
    private String seller;

    @Dynamic
    @Field("item_spec_*")
    private Map<String,String> specMap;

    private static final long serialVersionUID = 1L;

    .....
}

f.操作类



import com.alibaba.fastjson.JSON;
import com.huazhu.edm.api.business.vo.TbItemVO;
import com.huazhu.edm.service.business.dao.TbItemDao;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.*;
import org.springframework.data.solr.core.query.result.HighlightEntry;
import org.springframework.data.solr.core.query.result.HighlightPage;
import org.springframework.data.solr.core.query.result.ScoredPage;
import org.springframework.data.solr.server.support.HttpSolrClientFactoryBean;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ItemSearchServiceImpl   {
    @Autowired
    private TbItemDao tbItemDao;
    @Autowired
    private SolrTemplate solrTemplate;
    /**
     * 导入商品数据到索引库中
     */
    public void importItemData(){
        List<TbItemVO> itemList = tbItemDao.selectList(new TbItemVO());
        //System.out.println("==商品列表==");
        for (TbItemVO item : itemList) {
            Map specMap = JSON.parseObject(item.getSpec(), Map.class);//将spec字段中的json字符串转换为map
            item.setSpecMap(specMap);//给带注解的字段赋值
            item.setItemPrice(item.getPrice()+"");
            System.out.println(item.getTitle());
        }
        solrTemplate.saveBeans(itemList);
        solrTemplate.commit();
        //System.out.println("==结束==");
    }
    /**
     * 添加或更新
     */
    public void add() {
        TbItemVO item=new TbItemVO();
        item.setId(100L);
        item.setBrand("华为");
        item.setCategory("手机");
        item.setGoods_id(1L);
        item.setSeller("华为2号专卖店");
        item.setTitle("华为Mate9");
        item.setPrice(new BigDecimal(2000));
        item.setItemPrice(item.getPrice() + "");
        solrTemplate.saveBean(item);
        solrTemplate.commit();
    }

    /**
     * 按主键查询
     * @param id
     * @return
     */
    public void searchById(int id) {
        TbItemVO tbItem = solrTemplate.getById(id, TbItemVO.class);
        System.out.println(tbItem.getTitle());
        System.out.println(tbItem.getItemPrice());
    }

    /**
     * 按主键删除
     * @param id
     * @return
     */
    public void deleteById(String id) {
        solrTemplate.deleteById(id);
        solrTemplate.commit();

    }
    /**
     * 删除所有
     */
    public void deleteAll() {
        Query query = new SimpleQuery("*:*");
        solrTemplate.delete(query);
        solrTemplate.commit();
    }
    /**
     * 分页查询
     * @param start
     * @param size
     */
    public void pageQuery(int start,int size){
        Query query=new SimpleQuery("*:*");
        query.setOffset(start);//开始索引(默认0)start:(page-1)*rows
        query.setRows(size);//每页记录数(默认10)//rows:rows
        ScoredPage<TbItemVO> page =solrTemplate.queryForPage(query, TbItemVO.class);
        List<TbItemVO> list = page.getContent();
        for(TbItemVO item:list){
            System.out.println(item.getTitle() +item.getItemPrice());
        }
    }

    /**
     * 复杂条件搜索
     * @return
     */
    public void search() {

        //构造json字符串
        String searchStr = new String("{'keywords':'华为','category':'手机','brand':'华为'," +
                "'spec':{'机身内存':'16G','网络':'联通3G'},'price':'1000-3000'," +
                "'pageNo':1,'pageSize':10,'sortField':'price','sort':'ASC'}");
        Map searchMap = JSON.parseObject(searchStr, Map.class);


        Map<String, Object> resultMap = new HashMap<>();
        //1.先获取从页面传递过来的参数的值   通过KEY获取
        String keywords = (String)searchMap.get("keywords");//获取主查询的条件

        //2.设置主查询的条件
        HighlightQuery query =  new SimpleHighlightQuery();
        Criteria criteria = new Criteria("item_keywords");
        criteria.is(keywords);
        query.addCriteria(criteria);
        //3.设置高亮查询的条件   设置高亮显示的域  设置前缀  设置后缀
        HighlightOptions hightoptions = new HighlightOptions();
        hightoptions.addField("item_title");//设置高亮显示的域
        hightoptions.setSimplePrefix("<em style=\"color:red\">");
        hightoptions.setSimplePostfix("</em>");
        query.setHighlightOptions(hightoptions);

        //4.设置过滤条件  商品分类的过滤
        if (searchMap.get("category") != null && !"".equals(searchMap.get("category"))) {
            Criteria fiterCriteria = new Criteria("item_category").is(searchMap.get("category"));
            FilterQuery filterQuery = new SimpleFilterQuery(fiterCriteria);
            query.addFilterQuery(filterQuery);
        }

        //5.设置品牌的过滤
        if (searchMap.get("brand") != null && !"".equals(searchMap.get("brand"))) {
            Criteria fitercriteria = new Criteria("item_brand").is(searchMap.get("brand"));
            FilterQuery filterquery = new SimpleFilterQuery(fitercriteria);
            query.addFilterQuery(filterquery);
        }

        //6.设置规格的过滤条件
        if (searchMap.get("spec") != null) {
            Map<String,String> spec = (Map<String, String>) searchMap.get("spec");

            for (String key : spec.keySet()) {
                String value = spec.get(key);
                Criteria fiterCriteria = new Criteria("item_spec_"+key).is(value);//item_spec_网络:3G
                FilterQuery filterquery = new SimpleFilterQuery(fiterCriteria);
                query.addFilterQuery(filterquery);//
            }
        }

        //7.按照价格筛选
        if (StringUtils.isNotBlank((CharSequence) searchMap.get("price"))){
            //item_price:[10 TO 20]
            String[] split = searchMap.get("price").toString().split("-");
            SimpleFilterQuery filterQuery = new SimpleFilterQuery();
            Criteria itemPrice = new Criteria("item_price");
            //如果有* 语法是不支持的
            if(!split[1].equals("*")){
                itemPrice.between(split[0],split[1],true,true);
            }else {
                itemPrice.greaterThanEqual(split[0]);
            }
            filterQuery.addCriteria(itemPrice);
            query.addFilterQuery(filterQuery);
        }
        //8.分页查询
        Integer pageNo = (Integer) searchMap.get("pageNo");//提取页面

        if (pageNo==null){
            pageNo =1;
        }
        Integer pageSize = (Integer) searchMap.get("pageSize");//每页记录数
        if (pageSize==null){
            pageSize=20;
        }
        query.setOffset((pageNo-1)*pageSize);//从第几条记录查询
        query.setRows(pageSize);

        //9.排序
        String sortValue = (String) searchMap.get("sort");
        String sortField = (String) searchMap.get("sortField");//排序字段
        if (StringUtils.isNotBlank(sortField)){
            if (sortValue.equals("ASC")){
                Sort sort = new Sort(Sort.Direction.ASC, "item_" + sortField);
                query.addSort(sort);
            }
            if (sortValue.equals("DESC")){
                Sort sort = new Sort(Sort.Direction.DESC, "item_" + sortField);
                query.addSort(sort);
            }
        }

        //10.执行查询 获取高亮数据
        HighlightPage<TbItemVO> highlightPage = solrTemplate.queryForHighlightPage(query, TbItemVO.class);

        List<HighlightEntry<TbItemVO>> highlighted = highlightPage.getHighlighted();
        for (HighlightEntry<TbItemVO> tbItemHighlightEntry : highlighted) {
            TbItemVO entity = tbItemHighlightEntry.getEntity();//实体对象 现在是没有高亮的数据的

            List<HighlightEntry.Highlight> highlights = tbItemHighlightEntry.getHighlights();
            //如有高亮,就取高亮
            if(highlights!=null && highlights.size()>0 && highlights.get(0)!=null &&  highlights.get(0).getSnipplets()!=null && highlights.get(0).getSnipplets().size()>0) {
                entity.setTitle(highlights.get(0).getSnipplets().get(0));
            }
        }
        List<TbItemVO> tbItems = highlightPage.getContent();//获取高亮的文档的集合
        //11.执行查询
        System.out.println("结果"+tbItems.size());
        //12.获取结果集  返回
        resultMap.put("rows",tbItems);
        resultMap.put("totalPages",highlightPage.getTotalPages());//返回总页数
        resultMap.put("total",highlightPage.getTotalElements());//返回总记录数

        for (String s : resultMap.keySet()) {
            System.out.println(s+":"+resultMap.get(s));
        }
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值