Linux环境安装solr以及SpringDataSolr的使用

solr的安装

01环境准备

环境要求
  • VMware Linux CentOS-6.5。
  • JDK 1.7.0_07
  • Tomcat-7.0.52。

02开始安装

第一步:目录准备,在usr/local/目录下创建solr目录。

图片.png

并将apache-tomcat-7.0.52.tar.gz上传至Linux,安装tomcat到此目录下(上传工具可以使用FileZilla Client)。

图片.png
图片.png

第二步:把solr-4.10.3的压缩包上传到Linux系统。并解压得到solr-4.10.3文件夹。(我安装的是solr-4.10.3。)


图片.png

第二步:将/usr/local/src/solr-4.10.3/dist目录下的solr-4.10.3.war包复制到tomcat(我tomcat安装路径为/usr/local/tomcat7)的wepapp下面改名为solr.war,并启动tomcat解压solr.war。

图片.png

第三步:删除solr.war包,注意一定要先关闭tomcat再删除solr.war包,否则解压后的solr工程文件夹也会被删除。

图片.png

第四步:添加solr工程依赖的jar包。将/usr/local/src/solr-4.10.3/example/lib/ext下面的所有jar包都复制到solr工程WEB-INF/lib下面。


图片.png

第五步:添加solrhome:将/usr/local/src/solr-4.10.3/example下面的solr目录,复制到/usr/local/solr/下面,并改名为solrhome。

图片.png
图片.png

第六步:修改solr工程的配置web.xml文件。将web.xml中的 env-entry 标签中的env-entry-value路径改为/usr/local/solr/solrhome,注意要去掉 env-entry 标签的注释

图片.png
图片.png

第七步:启动Tomcat,在浏览器中输入http://192.168.25.200:8080/solr。访问solr页面。出现下面页面代表安装成功。

图片.png

SpringDataSolr的使用

IK Analyzer

IK Analyzer 是一个开源的,基亍 java 语言开发的轻量级的中文分词工具包。从 2006年 12 月推出 1.0 版开始, IKAnalyzer 已经推出了 4 个大版本。最初,它是以开源项目Luence 为应用主体的,结合词典分词和文法分析算法的中文分词组件。从 3.0 版本开始,IK 发展为面向 Java 的公用分词组件,独立亍 Lucene 项目,同时提供了对 Lucene 的默认优化实现。在 2012 版本中,IK 实现了简单的分词歧义排除算法,标志着 IK 分词器从单纯的词典分词向模拟语义分词衍化。

配置IK Analyzer
  • 1、把IKAnalyzer2012FF_u1.jar 添加到 solr 工程的 lib 目录下
  • 2、创建WEB-INF/classes文件夹 把扩展词典、停用词词典、配置文件放到 solr 工程的 WEB-INF/classes 目录下。
  • 3、修改 Solrhome 的 schema.xml 文件,配置一个 FieldType,使用 IKAnalyzer
<fieldType name="text_ik" class="solr.TextField">
     <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>

配置域

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

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

修改solrhome的schema.xml 文件 设置业务系统 Field

    <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" />
复制域

复制域的作用在于将某一个Field中的数据复制到另一个域中,扩大搜索范围。

<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"/>
动态域

当我们需要动态扩充字段时,我们需要使用动态域。对于品优购,规格的值是不确定的,所以我们需要使用动态域来实现。需要实现的效果如下:

<dynamicField name="item_spec_*" type="string" indexed="true" stored="true" />  

搭建工程

引入依赖
   <dependencies>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-solr</artifactId>
        <version>1.5.5.RELEASE</version>
    </dependency> 
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.9</version>
    </dependency>
  </dependencies>
配置文件

在src/main/resources下创建 applicationContext-solr.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:solr="http://www.springframework.org/schema/data/solr"
    xsi:schemaLocation="http://www.springframework.org/schema/data/solr 
        http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- solr服务器地址 -->
    <solr:solr-server id="solrServer" url="http://192.168.25.200:8080/solr" />
    <!-- solr模板,使用solr模板可对索引库进行CRUD的操作 -->
    <bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
        <constructor-arg ref="solrServer" />
    </bean>
</beans>
编写代码
创建pojo
package com.cehae.pojo;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

import org.apache.solr.client.solrj.beans.Field;

public class Item 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;

    @Override
    public String toString() {
        return "TbItem [id=" + id + ", title=" + title + ", sellPoint=" + sellPoint + ", price=" + price
                + ", stockCount=" + stockCount + ", num=" + num + ", barcode=" + barcode + ", image=" + image
                + ", categoryid=" + categoryid + ", status=" + status + ", createTime=" + createTime + ", updateTime="
                + updateTime + ", itemSn=" + itemSn + ", costPirce=" + costPirce + ", marketPrice=" + marketPrice
                + ", isDefault=" + isDefault + ", goodsId=" + goodsId + ", sellerId=" + sellerId + ", cartThumbnail="
                + cartThumbnail + ", category=" + category + ", brand=" + brand + ", spec=" + spec + ", seller="
                + seller + "]";
    }

    private static final long serialVersionUID = 1L;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title == null ? null : title.trim();
    }

    public String getSellPoint() {
        return sellPoint;
    }

    public void setSellPoint(String sellPoint) {
        this.sellPoint = sellPoint == null ? null : sellPoint.trim();
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public Integer getStockCount() {
        return stockCount;
    }

    public void setStockCount(Integer stockCount) {
        this.stockCount = stockCount;
    }

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }

    public String getBarcode() {
        return barcode;
    }

    public void setBarcode(String barcode) {
        this.barcode = barcode == null ? null : barcode.trim();
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image == null ? null : image.trim();
    }

    public Long getCategoryid() {
        return categoryid;
    }

    public void setCategoryid(Long categoryid) {
        this.categoryid = categoryid;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status == null ? null : status.trim();
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public String getItemSn() {
        return itemSn;
    }

    public void setItemSn(String itemSn) {
        this.itemSn = itemSn == null ? null : itemSn.trim();
    }

    public BigDecimal getCostPirce() {
        return costPirce;
    }

    public void setCostPirce(BigDecimal costPirce) {
        this.costPirce = costPirce;
    }

    public BigDecimal getMarketPrice() {
        return marketPrice;
    }

    public void setMarketPrice(BigDecimal marketPrice) {
        this.marketPrice = marketPrice;
    }

    public String getIsDefault() {
        return isDefault;
    }

    public void setIsDefault(String isDefault) {
        this.isDefault = isDefault == null ? null : isDefault.trim();
    }

    public Long getGoodsId() {
        return goodsId;
    }

    public void setGoodsId(Long goodsId) {
        this.goodsId = goodsId;
    }

    public String getSellerId() {
        return sellerId;
    }

    public void setSellerId(String sellerId) {
        this.sellerId = sellerId == null ? null : sellerId.trim();
    }

    public String getCartThumbnail() {
        return cartThumbnail;
    }

    public void setCartThumbnail(String cartThumbnail) {
        this.cartThumbnail = cartThumbnail == null ? null : cartThumbnail.trim();
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category == null ? null : category.trim();
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand == null ? null : brand.trim();
    }

    public String getSpec() {
        return spec;
    }

    public void setSpec(String spec) {
        this.spec = spec == null ? null : spec.trim();
    }

    public String getSeller() {
        return seller;
    }

    public void setSeller(String seller) {
        this.seller = seller == null ? null : seller.trim();
    }
}
创建测试类TestTemplate.java开始测试
package com.cehae.test;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.result.ScoredPage;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.cehae.pojo.Item;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext-solr.xml")
public class TestTemplate {

    @Autowired
    private SolrTemplate solrTemplate;

    /**
     * 添加数据
     */
    @Test
    public void testAdd() {

        // 创建商品
        Item item = new Item();
        // 设置域的数据
        item.setId(1L);// 注意是必填域
        item.setBrand("苹果");
        item.setCategory("手机");
        item.setGoodsId(1L);
        item.setSeller("苹果手机直营店");
        item.setTitle("苹果X");
        item.setPrice(new BigDecimal(8888));

        // 保存数据
        solrTemplate.saveBean(item);

        // 提交
        solrTemplate.commit();
    }

    /**
     * 根据主键查询
     */
    @Test
    public void testFindById() {

        Item item = solrTemplate.getById(1L, Item.class);

        System.out.println("item = " + item);
    }

    /**
     * 根据主键删除
     */
    @Test
    public void deleteById() {

        solrTemplate.deleteById("1");
        // 提交
        solrTemplate.commit();
    }

    /**
     * 根据主键批量删除
     */
    @Test
    public void deleteByIds() {

        List<String> list = new ArrayList();

        for (int i = 0; i <= 100; i++) {

            list.add(i + "");
        }

        solrTemplate.deleteById(list);
        // 提交
        solrTemplate.commit();
    }

    /**
     * 批量保存
     */
    @Test
    public void testAddList() {

        List<Item> list = new ArrayList();

        for (int i = 0; i < 100; i++) {
            Item item = new Item();
            item.setId(i + 1L);
            item.setBrand("苹果" + i);
            item.setCategory("手机");
            item.setGoodsId(1L);
            item.setSeller("苹果官方直营店");
            item.setTitle("苹果X" + i);
            item.setPrice(new BigDecimal(2000 + i));
            list.add(item);
        }

        solrTemplate.saveBeans(list);

        solrTemplate.commit();
    }

    /**
     * 分页查询
     */
    @Test
    public void testPageQuery() {

        // 查询表达式
        Query query = new SimpleQuery("*:*");
        // 设置开始索引
        query.setOffset(20);
        // 每页大小
        query.setRows(10);

        // 查询分页结果
        ScoredPage<Item> items = solrTemplate.queryForPage(query, Item.class);

        for (Item item : items) {
            System.out.println("item = " + item);
        }

        // ScoredPage扩展属性
        System.out.println("总记录数 = " + items.getTotalElements());
        System.out.println("总页数 = " + items.getTotalPages());
        System.out.println("每页大小  = " + items.getSize());
    }

    /**
     * 条件查询
     */
    @Test
    public void testPageQueryMulti() {
        // 查询表达式
        Query query = new SimpleQuery("*:*");

        // 添加条件:指定域和条件的值 contains:包含,is:匹配
        // Criteria criteria = new Criteria("item_category").is("手机");
        Criteria criteria = new Criteria("item_category").contains("手机");

        // 追加条件
        criteria = criteria.and("item_brand").contains("2");

        query.addCriteria(criteria);

        // 设置开始索引
        // query.setOffset(20);
        // 每页大小
        // query.setRows(10);

        // 查询分页结果
        ScoredPage<Item> items = solrTemplate.queryForPage(query, Item.class);

        for (Item item : items) {
            System.out.println("item = " + item);
        }

        // ScoredPage扩展属性
        System.out.println("总记录数 = " + items.getTotalElements());
        System.out.println("总页数 = " + items.getTotalPages());
        System.out.println("每页大小  = " + items.getSize());
    }

    /**
     * 删除所有
     */
    @Test
    public void testDeletAll() {

        // 设置删除条件
        Query query = new SimpleQuery("*:*");

        solrTemplate.delete(query);

        solrTemplate.commit();
    }
}

测试结果:

图片.png

源码下载

GitHub

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,039评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,223评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,916评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,009评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,030评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,011评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,934评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,754评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,202评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,433评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,590评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,321评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,917评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,568评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,738评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,583评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,482评论 2 352