我们已经了解了如何配置Spring Data Solr。 我们还学习了如何向Solr索引添加新文档,如何更新现有文档的信息以及从Solr索引删除文档。 现在是时候继续前进,学习如何使用Spring Data Solr从Solr索引中搜索信息。 我们的搜索功能的要求如下:

  • 搜索功能必须返回标题或描述包含给定搜索词的所有待办事项。
  • 搜索必须不区分大小写。

我们可以按照以下步骤实现搜索功能:

  1. 创建一个查询方法。
  2. 使用创建的查询方法。

让我们继续研究如何使用查询方法实现搜索功能。

注意:这些博客条目提供了其他信息,有助于我们理解此博客条目中描述的概念:

  • 使用Maven运行Solr
  • Spring Data Solr教程:Solr简介
  • Spring Data Solr教程:配置
  • Spring Data Solr教程CRUD(几乎)

创建查询方法

查询方法是

  1. 添加到存储库界面。
  2. 用于指定在调用查询方法时执行的搜索查询。
  3. 用于构建静态查询(具有相同数量查询参数的查询)。

我们可以通过以下技术使用Spring Data Solr创建查询方法:

  • 从方法名称查询生成
  • 命名查询
  • @Query批注

在以下小节中将更详细地描述这些技术。

从方法名称查询生成

从方法名称生成查询是一种查询生成策略,其中从查询方法的名称解析执行的查询。

  1. 查询方法的名称必须以特殊的前缀开头,该前缀标识查询方法。 这些前缀是: find,findBy,get,getBy,read和readBy 。 解析执行的查询时,将从方法名称中删除此前缀。
  2. 属性表达式用于引用我们文档类的属性。
  3. 特殊关键字与属性表达式一起使用,以指定在创建的查询中使用的运算符。 在属性表达式之后,将这些关键字添加到查询方法的名称中。
  4. 我们可以通过在属性表达式之间添加AndOr关键字来组合属性表达式。
  5. 查询方法的参数计数必须等于其名称中使用的属性表达式的数量。

通过阅读以下资源,我们可以获得有关属性表达式和存储库关键字的更多信息:

  • Spring Data Solr参考手册:查询创建
  • Spring Data Solr参考手册:存储库查询关键字

我们记得,我们的搜索功能必须返回标题或描述包含给定搜索词的所有待办事项。 同样,我们的文档类具有两个在查询中使用的属性。 这些属性称为titledescription 。 通过执行以下步骤,我们可以创建满足搜索功能要求的方法名称:

  1. findBy前缀添加到方法名称的开头。
  2. 在前缀之后添加title属性的属性表达式。
  3. 在属性表达式之后添加Contains关键字。
  4. Or关键字添加到方法名称。
  5. Or关键字之后添加description属性的属性表达式。
  6. Contains关键字添加到方法名称。
  7. 在我们的查询方法中添加两个方法参数。 第一个参数与title属性匹配,第二个参数与description属性匹配。

TodoDocumentRepository接口的源代码如下所示:

import org.springframework.data.solr.repository.SolrCrudRepository;
import java.util.List;public interface TodoDocumentRepository extends SolrCrudRepository<TodoDocument, String> {public List<TodoDocument> findByTitleContainsOrDescriptionContains(String title, String description);
}

注意:如果搜索词包含多个单词,则此查询方法将不起作用。

命名查询

命名查询是在单独的属性文件中声明并连接到正确查询方法的查询。 以下描述了有关用于声明命名查询的属性文件的规则:

  • 属性文件的默认位置是META-INF / solr-named-queries.properties,但是我们可以使用@EnableSolrRepositories批注的namedQueriesLocation属性来配置位置。
  • 使用以下公式创建每个命名查询的键: [文档类的名称]。[命名查询的名称]

使用以下规则,将在属性文件中配置的命名查询与我们的存储库界面的查询方法进行匹配:

  • 执行命名查询的查询方法的名称必须与命名查询的名称相同。
  • 如果查询方法的名称与命名查询的名称不同,则必须使用@Query注释对查询方法进行注释,并且必须使用@Query注释的name属性配置命名查询的名称 。 。

通过执行以下步骤,我们可以使用命名查询实现查询方法:

  1. 指定命名查询。
  2. 创建查询方法。

下面将更详细地描述这些步骤。

指定命名查询

通过执行以下步骤,我们可以创建一个满足查询功能要求的命名查询:

  1. 创建包含命名查询的属性文件。
  2. 使用前面描述的公式为命名查询创建一个键。 由于文档类的名称为TodoDocument ,因此命名查询的键为TodoDocument.findByNamedQuery
  3. 使用Lucene查询解析器语法创建命名查询。 因为我们的查询必须返回标题或描述包含给定搜索词的文档,所以我们的查询是: title:*?0 * OR description:*?0 *?0替换为查询方法的第一个参数的值)。

META-INF / solr-named-query.properties文件的内容如下所示:

TodoDocument.findByNamedQuery=title:*?0* OR description:*?0*

创建查询方法

通过执行以下步骤,我们可以创建使用创建的命名查询的查询方法:

  1. findByNamedQuery()方法添加到TodoDocumentRepository接口。 这个方法返回TodoDocument对象的列表中,并称为SEARCHTERM一个字符串参数。
  2. @Query注释注释该方法,并将其name属性的值设置为'TodoDocument.findByNamedQuery'。 不需要此步骤,因为查询方法的名称与命名查询的名称相同,但是我想在此处演示@Query注释的用法。

TodoDocumentRepository接口的源代码如下所示:

import org.springframework.data.solr.repository.Query;
import org.springframework.data.solr.repository.SolrCrudRepository;import java.util.List;public interface TodoDocumentRepository extends SolrCrudRepository<TodoDocument, String> {@Query(name = "TodoDocument.findByNamedQuery")public List<TodoDocument> findByNamedQuery(String searchTerm);
}

@Query注释

@Query批注可用于指定在调用查询方法时执行的查询。 通过执行以下步骤,我们可以创建满足搜索功能要求的查询方法:

  1. findByQueryAnnotation()方法添加到TodoDocumentRepository接口。 这个方法返回TodoDocument对象的列表,它有一个名为SEARCHTERM一个字符串参数。
  2. @Query注释对方法进行注释。
  3. 将执行的查询设置为@Query批注的值。 我们可以使用Lucene查询解析器语法创建查询。 因为我们的查询必须返回标题或描述包含给定搜索词的文档,所以正确的查询是: title:*?0 * OR description:*?0 *?0替换为查询方法的第一个参数的值) 。

TodoDocumentRepository接口的源代码如下所示:

import org.springframework.data.solr.repository.Query;
import org.springframework.data.solr.repository.SolrCrudRepository;import java.util.List;public interface TodoDocumentRepository extends SolrCrudRepository<TodoDocument, String> {@Query("title:*?0* OR description:*?0*")public List<TodoDocument> findByQueryAnnotation(String searchTerm);
}

使用创建的查询方法

我们可以按照以下步骤使用创建的查询方法:

  1. TodoIndexService接口中声明search()方法。
  2. search()方法的实现添加到RepositoryTodoIndexService类。

在以下小节中将更详细地描述这些步骤。

声明搜索方法

我们的第一步是在TodoIndexService接口中声明搜索方法。 TodoIndexService接口的相关部分如下所示:

import java.util.List;public interface TodoIndexService {public List<TodoDocument> search(String searchTerm);
}

实施搜索方法

我们的第二步是实现search()方法。 我们的实现非常简单。 它通过调用TodoDocumentRepository接口的正确方法来获取TodoDocument对象的列表,并返回该列表。

查询方法的名称取决于用于创建查询方法的技术。 下面描述不同的实现。

从方法名称查询生成

当我们从查询方法的名称生成查询时,我们的实现通过调用TodoDocumentRepository接口的findByTitleContainsOrDescriptionContains()方法获取TodoDocument对象的列表,并返回该列表。

RepositoryTodoIndexService类的相关部分如下所示:

import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;@Service
public class RepositoryTodoIndexService implements TodoIndexService {@Resourceprivate TodoDocumentRepository repository;@Overridepublic List<TodoDocument> search(String searchTerm) {return repository.findByTitleContainsOrDescriptionContains(searchTerm, searchTerm);}
}

命名查询

如果使用命名查询,则我们的实现将通过调用TodoDocumentRepository接口的findByNamedQuery()方法获取TodoDocument对象的列表,并返回该列表。

RepositoryTodoIndexService类的相关部分如下所示:

import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;@Service
public class RepositoryTodoIndexService implements TodoIndexService {@Resourceprivate TodoDocumentRepository repository;@Overridepublic List<TodoDocument> search(String searchTerm) {return repository.findByNamedQuery(searchTerm);}
}

@Query注释

当我们使用@Query批注时,我们的实现通过调用TodoDocumentRepository接口的findByQueryAnnotation()方法获取TodoDocument对象的列表,并返回该列表。

RepositoryTodoIndexService类的相关部分如下所示:

import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;@Service
public class RepositoryTodoIndexService implements TodoIndexService {@Resourceprivate TodoDocumentRepository repository;@Overridepublic List<TodoDocument> search(String searchTerm) {return repository.findByQueryAnnotation(searchTerm);}
}

选择正确的查询创建技术

显而易见的问题是:

将查询方法添加到我们的Spring Data Solr存储库中的最佳方法是什么?

在为查询方法确定正确的查询创建技术时,可以使用以下准则:

  • 如果创建的查询非常简单,则从方法名称生成查询通常是最佳选择。 这种方法的问题在于,用这种方法实现“复杂”查询会导致方法名称冗长而丑陋。
  • 将查询保持在查询方法附近是一个好主意。 使用@Query批注的好处是,我们可以通过阅读存储库接口的源代码来查看执行的查询和查询方法。
  • 如果我们想将执行的查询与存储库接口分开,则应使用命名查询。 这种方法的问题是我们必须从属性文件中检查已执行的查询,这非常麻烦。

摘要

现在,我们已经了解了如何使用Spring Data Solr创建静态查询。 这篇博客文章告诉我们两件事:

  • 我们知道什么是查询方法,以及如何创建它们。
  • 我们熟悉各种查询创建技术,并且知道何时使用它们。

Github上提供了演示此博客条目中描述的概念的示例应用程序。 在本教程的下一部分中,我们将学习如何将自定义功能添加到单个存储库 。

参考: Spring Data Solr教程: Petri Kainulainen博客上来自我们JCG合作伙伴 Petri Kainulainen的查询方法 。

翻译自: https://www.javacodegeeks.com/2013/05/spring-data-solr-tutorial-query-methods.html

Spring Data Solr教程:查询方法相关推荐

  1. Spring Data Solr教程:动态查询

    Solr通常被称为搜索服务器,我们可以在实现全文搜索功能时使用它. 但是,当我们实现从搜索表单获取其输入的搜索功能时,利用Solr的性能通常是明智的. 在这种情况下,执行的搜索查询取决于收到的输入. ...

  2. Spring Data Solr教程:将自定义方法添加到单个存储库

    我的Spring Data Solr教程的前一部分教我们如何使用查询方法创建静态查询. 自然而然的下一步将是描述如何使用Spring Data Solr创建动态查询. 但是,在继续讨论该主题之前,我们 ...

  3. Spring Data Solr教程:向所有存储库添加自定义方法

    如果我们在现实生活中的软件项目中使用Spring Data Solr,很可能我们迟早会遇到一个要求,该要求指出我们的应用程序必须能够与本地Solr服务器和SolrCloud进行通信 . 目前,满足此要 ...

  4. Spring Data Solr教程:排序

    当我们实现单词搜索功能时,我们通常希望通过使用每个搜索结果的相关性以降序对搜索结果进行排序. 这也是Solr的默认行为. 但是,在某些情况下,有必要手动指定排序顺序. 一种此类情况是"常规& ...

  5. Spring Data Solr教程:分页

    在我的Spring Data Solr教程的较早部分中,我们实现了一个简单的搜索功能,该功能用于搜索待办事项的信息. 我们搜索功能的当前实现将所有搜索结果显示在一个页面中. 对于大多数现实生活中的应用 ...

  6. Spring Data Solr教程:CRUD(差不多)

    在我的Spring Data Solr教程的上一部分中,我们学习了如何配置Spring Data Solr. 现在该迈出一步,了解我们如何管理Solr实例中存储的信息. 此博客文章描述了我们如何向So ...

  7. Spring Data Solr教程:Solr简介

    大多数应用程序必须具有某种搜索功能. 问题在于搜索功能通常是巨大的资源消耗,它们可能通过给数据库造成沉重的负担而破坏我们应用程序的性能. 因此,将负载转移到外部搜索服务器是个好主意. 这是我的Spri ...

  8. Spring Data Solr教程:配置

    在我的Spring Data Solr教程的上一部分中,我们了解到Solr提供了一个类似REST的HTTP API,该API可用于向Solr索引添加信息并针对索引数据执行查询. 问题在于,在开发环境中 ...

  9. solr crud_Spring Data Solr教程:CRUD(差不多)

    solr crud 在我的Spring Data Solr教程的上一部分中,我们学习了如何配置Spring Data Solr. 现在该迈出一步,了解我们如何管理Solr实例中存储的信息. 此博客文章 ...

最新文章

  1. KS001 基于Springboot机票预订系统
  2. R语言应用实战-基于R语言的判别分析:fisher判别法,距离判别法以及Bayers判别法(附源代码)
  3. 3638MySQL数据库应用答案_Mysql数据库多实例配置
  4. Junit Test使用样例
  5. Java中字符输入输出流
  6. Vue-Access-Control:前端用户权限控制解决方案
  7. ASP.NET MVC 小小总结
  8. evernote 的美中不足
  9. ACL2020论文:使用强化学习为机器翻译生成对抗样本
  10. 国军标GJB150A霉菌试验详解
  11. protel99se基本教程及使用教程
  12. Unity VR游戏教程
  13. c语言中front是什么,front用法,关于front的用法
  14. 设备管理与检修方式的发展史(转)
  15. cmath中常用的函数
  16. 虚拟机设置静态ip(固定ip地址)
  17. Gradle下载、安装、配置
  18. SmartX 超融合支撑 Rhapsody 医疗集成引擎运行效率实测详解 | 场景测评
  19. php基础从入门到面向对象(大合集)
  20. 光波导的入射耦合和出射耦合区域

热门文章

  1. 深入浅出 Java 中的包装类
  2. 怎样增强MyEclipse的代码自动提示功能
  3. 浅谈大型网站之负载均衡架构
  4. 存放80000000学生成绩的集合,怎么统计平均分性能高
  5. EL表达式和Jstl常见的用法
  6. 构建SpringCloud项目基础框架
  7. Linux中安装nc(netcat)常见问题
  8. 最大子序列和问题的解(共4种,层层推进)
  9. 一文理清RocketMQ顺序消费、重复消费、消息丢失问题
  10. Vue 媒体处理(摄像头,截图,播放本地视频)