热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SpringDataSolr搜索引擎进行开发教程

Solr安装与配置1.1Solr的介绍大多数搜索引擎应用都必须具有某种搜索功能,问题是搜索功能往往是巨大的资源消耗并且它们由于沉重的数据库加载而拖垮你的应用的性能

Solr安装与配置


1.1 Solr的介绍


  1. 大多数搜索引擎应用都必须具有某种搜索功能,问题是搜索功能往往是巨大的资源消耗并且它们由于沉重的数据库加载而拖垮你的应用的性能。这就是为什么转移负载到一个外部的搜索服务器是一个不错的主意,Apache Solr是一个流行的开源搜索服务器,它通过使用类似REST的HTTP API,这就确保你能从几乎任何编程语言来使用solr。

  2. Solr是一个开源搜索平台,用于构建搜索应用程序。 它建立在Lucene(全文搜索引擎)之上。 Solr是企业级的,快速的和高度可扩展的。使用Solr构建的应用程序非常复杂,可提供高性能。

  3. 为了在CNET网络的公司网站上添加搜索功能,YonikSeely于2004年创建了Solr。并在2006年1月,它成为Apache软件基金会下的一个开源项目。并于2016年发布最新版本Solr6.0,支持并行SQL查询的执行。 Solr可以和Hadoop一起使用。由于Hadoop处理大量数据,Solr帮助我们从这么大的源中找到所需的信息。不仅限于搜索,Solr也可以用于存储目的。像其他NoSQL数据库一样,它是一种非关系数据存储和处理技术。总之,Solr是一个可扩展的,可部署,搜索/存储引擎,优化搜索大量以文本为中心的数据。

1.2 Solr的安装


  1. 安装 Tomcat,解压缩即可。

  2. 解压 solr。

  3. 把 solr 下的dist目录solr-4.10.3.war部署到 Tomcat\webapps下(去掉版本号)。

  4. 启动 Tomcat解压缩 war 包

  5. 把solr下example/lib/ext 目录下的所有的 jar 包,添加到 solr 的工程中(\WEB-INF\lib目录下)。

  6. 创建一个 solrhome 。solr 下的/example/solr 目录就是一个 solrhome。复制此目录到D盘改名为solrhome

  7. 关联 solr 及 solrhome。需要修改 solr 工程的 web.xml 文件。

<env-entry><env-entry-name>solr/home</env-entry-name><env-entry-value>D:\tomcat_solr\solrhome</env-entry-value><env-entry-type>java.lang.String</env-entry-type>
</env-entry>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

8 . 启动 Tomcat

这里写图片描述


1.3中文分析器IK Analyzer


1.3.1 IK Analyzer简介

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

1.3.2 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>

  • 1
  • 2
  • 3
  • 4

1.4 配置域

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

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


1.4.1域

修改solrhome的schema.xml 文件 设置业务系统 Field(每个field对应一个表数据的字段,以下是根据数据库的一个表字段来设置的)

"item_goodsid" type="long" indexed="true" stored="true"/>
"item_title" type="text_ik" indexed="true" stored="true"/>
"item_price" type="double" indexed="true" stored="true"/>
"item_image" type="string" indexed="false" stored="true" />
"item_category" type="string" indexed="true" stored="true" />
"item_seller" type="text_ik" indexed="true" stored="true" />
"item_brand" type="string" indexed="true" stored="true" />

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

1.4.2复制域

复制域的作用在于将某一个Field中的数据复制到另一个域中(拥有多个域的字段,常用于多条件查询,就是一个输入框内,可以根据标题来搜索,也可以根据品牌名来搜索)

"item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
source="item_title" dest="item_keywords"/>
source="item_category" dest="item_keywords"/>
source="item_seller" dest="item_keywords"/>
source="item_brand" dest="item_keywords"/>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

1.4.3动态域

当我们需要动态扩充字段时,我们需要使用动态域。比如对于商品规格的值是不确定的,所以我们需要使用动态域来实现。需要实现的效果如下: 
这里写图片描述

配置:

"item_spec_*" type="string" indexed="true" stored="true" />

  • 1

Spring Data Solr入门


2.1 Spring Data Solr简介

虽然支持任何编程语言的能力具有很大的市场价值,你可能感兴趣的问题是:我如何将Solr的应用集成到Spring中?Spring Data Solr就是为了方便Solr的开发所研制的一个框架,其底层是对SolrJ(官方API)的封装。


2.2 Spring Data Solr入门小Demo


2.2.1 搭建工程

(1) 创建maven工程,pom.xml中引入依赖

<dependencies><dependency><groupId>org.springframework.datagroupId><artifactId>spring-data-solrartifactId><version>1.5.5.RELEASEversion>dependency> <dependency><groupId>org.springframeworkgroupId><artifactId>spring-testartifactId><version>4.2.4.RELEASEversion>dependency><dependency><groupId>junitgroupId><artifactId>junitartifactId><version>4.9version>dependency>dependencies>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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


<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.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><solr:solr-server id="solrServer" url="http://127.0.0.1:8080/solr" /><bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate"><constructor-arg ref="solrServer" />bean>
beans>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

2.2.2 @Field 注解

创建一个TbItem实体类,属性使用@Field注解标识 。 如果属性与配置文件定义的域名称不一致,需要在注解中指定域名称。

public class TbItem implements Serializable{@Fieldprivate 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 specMap;public Map getSpecMap() {return specMap;}public void setSpecMap(Map specMap) {this.specMap = specMap;}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();}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253

2.2.3 增加(修改)

创建测试类TestTemplate.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locatiOns="classpath:applicationContext-solr.xml")
public class TestTemplate {@Autowiredprivate SolrTemplate solrTemplate;@Testpublic void testAdd(){TbItem item=new TbItem();item.setId(1L);item.setBrand("华为");item.setCategory("手机");item.setGoodsId(1L);item.setSeller("华为2号专卖店");item.setTitle("华为Mate9");item.setPrice(new BigDecimal(2000)); solrTemplate.saveBean(item);solrTemplate.commit();}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

2.2.4 按主键查询

@Testpublic void testFindOne(){TbItem item = solrTemplate.getById(1, TbItem.class);System.out.println(item.getTitle());}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.2.5 按主键删除

@Testpublic void testDelete(){solrTemplate.deleteById("1");solrTemplate.commit();}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.2.6 分页查询

首先循环插入100条测试数据

@Testpublic void testAddList(){List list=new ArrayList();for(int i=0;i<100;i++){TbItem item=new TbItem();item.setId(i+1L);item.setBrand("华为");item.setCategory("手机");item.setGoodsId(1L);item.setSeller("华为2号专卖店");item.setTitle("华为Mate"+i);item.setPrice(new BigDecimal(2000+i)); list.add(item);}solrTemplate.saveBeans(list);solrTemplate.commit();}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

编写分页查询测试代码:

@Testpublic void testPageQuery(){Query query=new SimpleQuery("*:*");query.setOffset(20);//开始索引(默认0)query.setRows(20);//每页记录数(默认10)ScoredPage page = solrTemplate.queryForPage(query, TbItem.class);System.out.println("总记录数:"+page.getTotalElements());List list = page.getContent();showList(list);} //显示记录数据private void showList(List list){ for(TbItem item:list){System.out.println(item.getTitle() +item.getPrice());} }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

2.2.7 条件查询

Criteria 用于对条件的封装:

@Testpublic void testPageQueryMutil(){ Query query=new SimpleQuery("*:*");Criteria criteria=new Criteria("item_title").contains("2");criteria=criteria.and("item_title").contains("5"); query.addCriteria(criteria);//query.setOffset(20);//开始索引(默认0)//query.setRows(20);//每页记录数(默认10)ScoredPage page = solrTemplate.queryForPage(query, TbItem.class);System.out.println("总记录数:"+page.getTotalElements());List list = page.getContent();showList(list);}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.2.8 删除全部数据

@Testpublic void testDeleteAll(){Query query=new SimpleQuery("*:*");solrTemplate.delete(query);solrTemplate.commit();}

推荐阅读
  • Spring – Bean Life Cycle
    Spring – Bean Life Cycle ... [详细]
  • 原文网址:https:www.cnblogs.comysoceanp7476379.html目录1、AOP什么?2、需求3、解决办法1:使用静态代理4 ... [详细]
  • 在PHP中如何正确调用JavaScript变量及定义PHP变量的方法详解 ... [详细]
  • 快速掌握Tomcat 8.5.40的配置与应用技巧 ... [详细]
  • 深入解析Struts、Spring与Hibernate三大框架的面试要点与技巧 ... [详细]
  • Maven Web项目创建时JSP文件常见错误及解决方案
    Maven Web项目创建时JSP文件常见错误及解决方案 ... [详细]
  • 在Java Web服务开发中,Apache CXF 和 Axis2 是两个广泛使用的框架。CXF 由于其与 Spring 框架的无缝集成能力,以及更简便的部署方式,成为了许多开发者的首选。本文将详细介绍如何使用 CXF 框架进行 Web 服务的开发,包括环境搭建、服务发布和客户端调用等关键步骤,为开发者提供一个全面的实践指南。 ... [详细]
  • CSS3 @font-face 字体应用技术解析与实践
    在Web前端开发中,HTML教程和CSS3的结合使得网页设计更加多样化。长期以来,Web设计师受限于“web-safe”字体的选择。然而,CSS3中的`@font-face`规则允许从服务器端加载自定义字体,极大地丰富了网页的视觉效果。通过这一技术,设计师可以自由选择和使用各种字体,提升用户体验和页面美观度。本文将深入解析`@font-face`的实现原理,并提供实际应用案例,帮助开发者更好地掌握这一强大工具。 ... [详细]
  • 作为软件工程专业的学生,我深知课堂上教师讲解速度之快,很多时候需要课后自行消化和巩固。因此,撰写这篇Java Web开发入门教程,旨在帮助初学者更好地理解和掌握基础知识。通过详细记录学习过程,希望能为更多像我一样在基础方面还有待提升的学员提供有益的参考。 ... [详细]
  • camel_使用Camel在来自不同来源的Solr中索引数据
    camelApacheSolr是建立在Lucene之上的“流行的,快速的开源企业搜索平台”。为了进行搜索(并查找结果),通常需要从不同的源(例如内容管理 ... [详细]
  • HTML中span元素为何会脱离li元素对齐?
    在HTML布局中,有时会遇到span元素未能与li元素保持对齐的问题。本文将探讨这一现象的原因,并提供解决方案。 ... [详细]
  • 本文对SQL Server系统进行了基本概述,并深入解析了其核心功能。SQL Server不仅提供了强大的数据存储和管理能力,还支持复杂的查询操作和事务处理。通过MyEclipse、SQL Server和Tomcat的集成开发环境,可以高效地构建银行转账系统。在实现过程中,需要确保表单参数与后台代码中的属性值一致,同时在Servlet中处理用户登录验证,以确保系统的安全性和可靠性。 ... [详细]
  • DVWA学习笔记系列:深入理解CSRF攻击机制
    DVWA学习笔记系列:深入理解CSRF攻击机制 ... [详细]
  • 全面解析JavaScript代码注释技巧与标准规范
    在Web前端开发中,JavaScript代码的可读性和维护性至关重要。本文将详细介绍如何有效地使用注释来提高代码的可读性,并探讨JavaScript代码注释的最佳实践和标准规范。通过合理的注释,开发者可以更好地理解和维护复杂的代码逻辑,提升团队协作效率。 ... [详细]
  • 系统转换的三种方法及其具体应用分析
    系统转换是信息技术领域中常见的任务,本文详细探讨了三种主要的系统转换方法及其具体应用场景。这些方法包括:代码迁移、数据迁移和平台迁移。文章通过实例分析了每种方法的优势和局限性,并提供了实际操作中的注意事项和技术要点。例如,代码迁移适用于从VB6获取网页源码,数据迁移在Ubuntu中用于隐藏侧边栏,而平台迁移则涉及Tomcat 6.0的使用和谷歌爬虫的测试。此外,文章还讨论了蓝翰互动PHP面试和5118 SEO工具在系统转换中的应用,为读者提供了全面的技术参考。 ... [详细]
author-avatar
jystmj-2009
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有