Spring Data Solr入门

Spring Data Solr是Spring Data项目的扩展,该项目旨在简化Apache Solr在Spring应用程序中的使用。 请注意,这不是Spring(数据)或Solr的简介。 我认为您至少对这两种技术都有一些基本的了解。 在下面的文章中,我将展示如何使用Spring Data存储库访问Spring应用程序中的Solr功能。

组态

首先,我们需要一个正在运行的Solr服务器。 为简单起见,我们将使用当前Solr版本(在撰写本文时为4.5.1)随附的示例配置,并在官方Solr教程中进行了描述。 因此,我们只需要下载Solr,将其解压缩到我们选择的目录中,然后从<solr home> / example目录运行java -jar start.jar。

现在,让我们转到演示应用程序,并使用maven添加Spring Data Solr依赖项:

<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-solr</artifactId><version>1.0.0.RELEASE</version>
</dependency>

在这个示例中,我使用Spring Boot设置了一个小的示例Spring应用程序。 我为此使用了以下Spring Boot依赖项和Spring Boot父pom:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>

如果您还没有使用过Spring Boot,请不要担心。 这些依赖关系主要充当常见(Spring)依赖关系的捷径,并稍微简化了配置。 如果要将Spring Data Solr集成到现有的Spring应用程序中,则可以跳过Spring Boot依赖项。

Spring bean的配置非常简单,我们只需要自己定义两个bean:

@ComponentScan
@EnableSolrRepositories("com.mscharhag.solr.repository")
public class Application {@Beanpublic SolrServer solrServer() {return new HttpSolrServer("http://localhost:8983/solr");}@Beanpublic SolrTemplate solrTemplate(SolrServer server) throws Exception {return new SolrTemplate(server);}
}

solrServer bean用于连接到正在运行的Solr实例。 由于Spring Data Solr使用Solrj,因此我们创建了Solrj HttpSolrServer实例。 通过使用EmbeddedSolrServer也可以使用嵌入式Solr服务器。 SolrTemplate提供了与Solr一起使用的通用功能(类似于Spring的JdbcTemplate)。 创建Solr存储库需要使用solrTemplate bean。 另请注意@EnableSolrRepositories批注。 有了这个注释,我们告诉Spring Data Solr在指定的包中查找Solr存储库。

建立文件

在查询Solr之前,我们必须将文档添加到索引。 要定义文档,我们创建一个POJO并向其中添加Solrj批注。 在此示例中,我们将使用一个简单的Book类作为文档:

public class Book {@Fieldprivate String id;@Fieldprivate String name;@Fieldprivate String description;@Field("categories_txt")private List<Category> categories;// getters/setters
}
public enum Category {EDUCATION, HISTORY, HUMOR, TECHNOLOGY, ROMANCE, ADVENTURE
}

每本书都有唯一的ID,名称,说明,并属于一个或多个类别。 请注意,默认情况下,Solr需要每个文档的String类型的唯一ID。 应该添加到Solr索引的字段使用Solrj @Field注释进行注释。 默认情况下,Solrj尝试将文档字段名称映射到同名的Solr字段。 Solr示例配置已经定义了名为id,名称和描述的Solr字段,因此不必将这些字段添加到Solr配置中。

如果要更改Solr字段定义,可以在<solr home> /example/solr/collection1/conf/schema.xml中找到示例配置文件。 在此文件中,您应该找到以下字段定义:

<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" /> 
<field name="name" type="text_general" indexed="true" stored="true" />
<field name="description" type="text_general" indexed="true" stored="true"/>

一般而言,书名比书名更好。 但是,通过使用名称,我们可以使用默认的Solr字段配置。 因此,出于简单原因,我选择名称而不是标题。

对于类别,我们必须使用@Field批注手动定义字段名称:Categories_txt。 这与Solr示例中名为* _txt的动态字段匹配。 也可以在schema.xml中找到此字段定义:

<dynamicField name="*_txt" type="text_general"   indexed="true"  stored="true" multiValued="true"/>

创建一个仓库

Spring Data使用存储库来简化各种数据访问技术的使用。 仓库基本上是一个接口,其实现由Spring Data在应用程序启动时动态生成。 生成的实现基于存储库接口中使用的命名约定。 如果这是您的新手,建议阅读使用Spring数据存储库 。

Spring Data Solr使用相同的方法。 我们在接口内部使用命名约定和注释来定义访问Solr功能所需的方法。 我们从一个仅包含一种方法的简单存储库开始(稍后将添加更多方法):

public interface BookRepository extends SolrCrudRepository<Book, String> {List<Book> findByName(String name);}

通过扩展SolrCrudRepository,我们可以在存储库中获得一些常用方法,如save(),findAll(),delete()或count()。 使用接口方法findByName(String name)的定义,我们告诉Spring Data Solr创建一个方法实现,该方法实现向Solr查询书籍列表。 此列表中的书名应与传递的参数匹配。

可以使用Spring的DI功能将存储库实现注入到其他类中。 在此示例中,我们将存储库注入到简单的JUnit测试中:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class, loader=SpringApplicationContextLoader.class)
public class BookRepositoryTests {@Autowiredprivate BookRepository bookRepository;...
}

向Solr添加文档

现在是时候向Solr添加一些书籍了。 使用我们的存储库,这是一项非常简单的工作:

private void addBookToIndex(String name, String description, Category... categories) {Book book = new Book();book.setName(name);book.setDescription(description);book.setCategories(Arrays.asList(categories));book.setId(UUID.randomUUID().toString());bookRepository.save(book);
}private void createSampleData() {addBookToIndex("Treasure Island", "Best seller by R.L.S.", Category.ADVENTURE);addBookToIndex("The Pirate Island", "Oh noes, the pirates are coming!", Category.ADVENTURE, Category.HUMOR);...
}

增加分页并增强

假设我们有一个应用程序,用户可以在其中搜索书籍。 我们需要查找名称或描述与用户给出的搜索查询相匹配的书籍。 出于性能原因,我们希望添加某种分页功能,该分页功能一次只能向用户显示10个搜索结果。

让我们在存储库界面中为此创建一个新方法:

Page<Book> findByNameOrDescription(@Boost(2) String name, String description, Pageable pageable);

方法名称findByNameOrDescription告诉Spring Data Solr查询名称或描述与传递的参数匹配的书籍对象。 为了支持分页,我们添加了Pageable参数,并将返回类型从List <Book>更改为Page <Book>。 通过在名称参数中添加@Boost批注,可以增强名称与搜索参数匹配的书籍。 这是有道理的,因为这些书通常对用户更感兴趣。

如果现在我们要查询包含10个元素的第一页,我们只需要做:

Page<Book> booksPage = bookRepository.findByNameOrDescription
(searchString, searchString, new PageRequest(0, 10));

除前10个搜索结果外,Page <Book>提供了一些用于建立分页功能的有用方法:

booksPage.getContent()       // get a list of (max) 10 books
booksPage.getTotalElements() // total number of elements (can be >10)
booksPage.getTotalPages()    // total number of pages
booksPage.getNumber()        // current page number
booksPage.isFirstPage()      // true if this is the first page
booksPage.hasNextPage()      // true if another page is available
booksPage.nextPageable()     // the pageable for requesting the next page
...

刻面

每当用户搜索书名时,我们都想向他显示不同类别中有多少本书符合给定的查询参数。 此功能称为分面搜索 ,Spring Data Solr直接支持此功能。 我们只需要向存储库接口添加另一种方法:

@Query("name:?0")
@Facet(fields = { "categories_txt" }, limit = 5)
FacetPage<Book> findByNameAndFacetOnCategories(String name, Pageable page);

这次查询将从@Query批注(包含Solr查询)而不是方法名称派生。 使用@Facet批注,我们告诉Spring Data Solr按类别对构面进行分类,并返回前五个构面。

也可以删除@Query批注并将方法名称更改为findByName,以达到相同的效果。 这种方法的一个小缺点是,对于调用者来说,这种存储库方法确实可以执行构面操作,这一点并不明显。 另外,方法签名可能与其他按名称搜索书籍的方法相冲突。

用法:

FacetPage<Book> booksFacetPage = bookRepository.findByNameAndFacetOnCategories(bookName, new PageRequest(0, 10));booksFacetPage.getContent(); // the first 10 booksfor (Page<? extends FacetEntry> page : booksFacetPage.getAllFacets()) {for (FacetEntry facetEntry : page.getContent()) {String categoryName = facetEntry.getValue();  // name of the categorylong count = facetEntry.getValueCount();      // number of books in this category// convert the category name back to an enumCategory category = Category.valueOf(categoryName.toUpperCase());}
}

请注意,booksFacetPage.getAllFacets()返回FacetEntry页面的集合。 这是因为@Facet批注允许您一次对多个字段进行构面。 每个FacetPage最多包含 五个FacetEntries(由@Facet的limit属性定义)。

突出显示

通常,在搜索结果列表中突出显示搜索查询的出现很有用(例如,由google或bing来完成)。 这可以通过(Spring Data)Solr的突出显示功能来实现。

让我们添加另一个存储库方法:

@Highlight(prefix = "<highlight>", postfix = "</highlight>")
HighlightPage<Book> findByDescription(String description, Pageable pageable);

@Highlight注释告诉Solr突出显示搜索到的描述的出现。

用法:

HighlightPage<Book> booksHighlightPage = bookRepository.findByDescription(description, new PageRequest(0, 10));booksHighlightPage.getContent(); // first 10 booksfor (HighlightEntry<Book> he : booksHighlightPage.getHighlighted()) {// A HighlightEntry belongs to an Entity (Book) and may have multiple highlighted fields (description)for (Highlight highlight : he.getHighlights()) {// Each highlight might have multiple occurrences within the descriptionfor (String snipplet : highlight.getSnipplets()) {// snipplet contains the highlighted text}}
}

如果使用此存储库方法查询描述包含字符串“ 金银岛”的书籍,则​​摘要可能如下所示:

<highlight>Treasure Island</highlight> is a tale of pirates and villains, maps, treasure and shipwreck, and is perhaps one of the best adventure story ever written.

在这种情况下, 金银岛位于说明的开头,并使用@Highlight注释中定义的前缀和后缀突出显示。 当向用户显示搜索结果时,此附加标记可用于标记查询的出现。

结论

Spring Data Solr提供了一种非常简单的方法来将Solr集成到Spring应用程序中。 使用存储库抽象,它遵循大多数其他Spring Data项目所做的相同设计原则。 我在使用Spring Data Solr时遇到的唯一小缺点是可以在此处和此处进行改进的文档。

  • 您可以在GitHub上找到此示例的完整源代码。

参考: mscharhag,Programming and Stuff博客上的JCG合作伙伴 Michael Scharhag的Spring Data Solr入门 。

翻译自: https://www.javacodegeeks.com/2013/11/getting-started-with-spring-data-solr.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366835.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个关于fixed抖动的小bug

前言 大家都知道position: fixed用于生成绝对定位的元素&#xff0c;相对于浏览器窗口进行定位。 元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。 突然发现自己之前写的网页有个小bug&#xff1a;在购买页面的…

BBS论坛(十八)

18.首页轮播图实现 &#xff08;1&#xff09;front/css/front_base.css .main-container{width: 990px;margin: 0 auto;overflow: hidden; } .lg-container{width: 730px;float:left; } .sm-container{width: 250px;float:right; } &#xff08;2&#xff09;front_base.html …

eureka-7-多网卡下的ip选择

目前没有需求,后面需要的话&#xff0c;再补充 只是简单使用的话&#xff0c;只需要指定ip即可 eureka.instance.ip-address:127.0.0.1转载于:https://www.cnblogs.com/wenq001/p/9884591.html

Java DB中的Java用户定义类型(UDT)

Java DB是基于Java编程语言和SQL的关系数据库管理系统。 这是Apache软件基金会的开源Derby项目的Oracle版本。 Java SE 7 SDK中包含Java DB。 用户定义类型&#xff08;UDT&#xff09;是Java类&#xff0c;其实例&#xff08;对象&#xff09;存储在数据库表列中。 UDT定义为…

php 字符串与数字相加,注意!PHP中字符串与数字的比较

在日常开发过程中&#xff0c; 运算符是我们每天都会接触到的。这个运算符中其实埋了非常多的坑&#xff0c;今天我们就来看下字符串和数字用比较需要注意的问题。首先来看看这些代码&#xff1a;echo "1234" " 1234" is . (1234 1234), PHP_EOL;echo …

腾讯Node.js基础设施TSW正式开源

经过六年的迭代与沉淀&#xff0c;腾讯Tencent Server Web (以下简称TSW)这一公司级运维组件于今日正式开源。TSW是面向WEB前端开发者&#xff0c;以提升问题定位效率为初衷&#xff0c;提供云抓包、全息日志和异常发现的Node.js基础设施。TSW每天为百亿次请求提供稳定服务&…

Luogu P1535 【游荡的奶牛】

搜索不知道为什么没有人写bfs觉得挺像是标准个bfs的 状态因为要统计次数&#xff0c;不能简单地跳过一个被经过的点这样的话&#xff0c;状态量会爆炸采用记忆化设dp[i][j][k]表示在第k分钟到达点(i,j)的方案数以地点时间作为状态避免同一状态被反复拓展这样&#xff0c;状态量…

ORM框架greenDao 2 (用于了解旧版本的使用方法,目前最新版本为3.2.2,使用注释的方式来生成)...

摘要&#xff1a; Android中对SQLite数据库使用&#xff0c;是一件非常频繁的事情。现今&#xff0c;也有非常多的SQLite处理的开源框架&#xff0c;其中最著名的greenDao&#xff0c;它以占用资源少&#xff0c;处理效率高等特点&#xff0c;成为优秀的ORM框架之一。那么对于g…

配置MySQL以进行ADF开发

大家好。 今天&#xff0c;我将向您展示如何为Oracle ADF开发配置MySQL数据库。 恕我直言&#xff0c;当您将ADF与其他数据库而不是Oracle DB一起使用时&#xff0c;您将无法使用Oracle ADF的全部功能&#xff0c;有时您会发现自己正在寻找解决方法&#xff0c;以实现某些行为…

linux 强行杀死进程,Linux如何查看进程、杀死进程、启动进程等常用命令

查进程杀进程使用kill命令结束进程&#xff1a;常用&#xff1a;Linux下还提供了一个killall命令&#xff0c;可以直接使用进程的名字而不是进程标识号&#xff0c;例如&#xff1a;进入到进程的执行文件所在的路径下&#xff0c;执行文件 ./文件名附&#xff1a;修改文件日期命…

React Native面试知识点

本文原创首发于公众号&#xff1a;ReactNative开发圈&#xff0c;转载需注明出处。 本文会不定期不断更新&#xff0c;想查看最新版本请移步至https://github.com/forrest23/react-native-interview 1.React Native相对于原生的ios和Android有哪些优势&#xff1f; 1.性能媲美…

KIE-WB / JBPM控制台Ng –配置

大家好&#xff0c;这是我上一篇文章中有关如何使用jBPM Console的后续文章 。 这篇文章的主要思想是描述为了在您自己的公司中使用它&#xff0c;您需要对jBPM Console NG进行一些最常见的配置。 但是在讨论技术细节之前&#xff0c;我们将介绍KIE Workbench&#xff08;KIE-W…

EasyUI常用控件禁用方法

来自&#xff1a;http://blog.csdn.net/jin_guang/article/details/36905387 特此感谢 1.validatebox可以用的用法:前两种适用于单个的validatebox; 第三种应用于整个form里面的输入框; <1>.$("#id").attr("readonly", true); ----- $("#id…

linux内核percpu变量声明,Linux kernel percpu变量解析

Linux 2.6 kernel 中的 percpu 变量是经常用到的东西&#xff0c;因为现在很多计算机都已经支持多处理器了&#xff0c;而且 kernel 默认都会被编译成 SMP 的&#xff0c;相对于原来多个处理器共享数据并进行处理的方式&#xff0c;用 percpu 变量在 SMP、NUMA 等架构下可以提高…

django组件 分页器

1 from django.shortcuts import render,HttpResponse2 3 # Create your views here.4 from app01.models import *5 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger6 7 def index(request):8 9 10 批量导入数据: 11 12 Booklist[] …

自己写一个H5项目CI系统

持续集成&#xff08;Continuous integration&#xff0c;简称CI)系统在软件自动化构建&#xff08;包括编译、发布、自动化测试&#xff09;方面有着重要的作用&#xff0c;在之前&#xff0c;前端项目简单&#xff0c;很多时候发布都只是一些简单的拷贝&#xff0c;而随着web…

25.QT-模型视图

模型视图设计模式的核心思想 使模型(数据)与视图(显示)相分离模型只需要对外提供标准接口存取数据,无需数据如何显示视图只需要自定义数据的显示方式,无需数据如何组织存储当数据发生改变时,会通过信号通知视图当用户与视图进行交互时,会通过信号向模型发送交互信息 在QT中提供…

休眠事实:多级访存

在多个级别上检索根实体及其子关联是很常见的。 在我们的示例中&#xff0c;我们需要加载一个包含其树&#xff0c;分支和叶子的森林&#xff0c;并且我们将尝试查看Hibernate对于三种集合类型的行为&#xff1a;集合&#xff0c;索引列表和包。 这是我们的类层次结构的样子&…

linux系统fuser命令,Linux系统使用Fuser命令的方法

fuser命令是一个非常聪明的unix实用程序&#xff0c;用于查找正在使用某个文件、目录或socket的进程。 它还提供有关拥有该进程的用户和访问类型的信息。。fuser工具显示了使用指定文件或文件系统的每个进程的进程ID(PID)。安装如果你的精简版运行fuser提示如下信息&#xff1a…

网络基础之 Nmap 命令

nmap......转载于:https://www.cnblogs.com/changha0/p/9898020.html