Spring专题

Spring Data Solr 教程与源码下载

Spring Data Solr的配置源码

Spring Data Solr的CRUD增删改查源码

Spring Data Solr排序和分页源码下载

Spring Data Solr 教程: 加入定制方法到所有仓储源码下载

Spring并不直接支持Solr云,见our application must be able to communicate with both a local Solr server and a SolrCloud,只能给Sor的仓储加入定制方法完成。

 

Spring Solr源码二

  以书店为案例,实体类如下:

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

  每本书都有一个唯一的ID,名称,描述和所属的一个或多个类别。Solr在默认情况下为每个文档需要String类型的唯一ID。需要添加到Solr索引的字段就要标注@ field注解。默认情况下SolrJ的尝试将文档字段名映射到同一个名字的Solr的字段。如果你想改变Solr的字段,在<solr home>/example/solr/collection1/conf/schema.xml下可以更改。

  下面建立一个仓储:

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

  下面调用这个仓储,将书籍Book加入:

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);
  ...
}

  加入分页功能,每页十个,在仓储中加入:

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

为了支持分页,我们加入参数Pageable,改变了返回类型为Page<Book>. 增加@Boost 启动那些名字匹配搜索参数的书籍。

如果你需要第一页0-10个元素,如下:

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

下面是Page的使用:

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

  只要用户给出一本书的名字,在不同分类中返回给他多少匹配给定这个名字的书,这称为faceted search,如下代码:

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

@Facet 我们告诉Spring数据返回查询Solr按类别排列的书籍,并返回五个。

调用:

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

高亮实现:

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

调用:

HighlightPage<Book> booksHighlightPage = bookRepository.findByDescription(description, new PageRequest(0, 10));
 
booksHighlightPage.getContent(); // first 10 books
 
for (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 description
    for (String snipplet : highlight.getSnipplets()) {
      // snipplet contains the highlighted text
    }
  }
}