42
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ SPRINGONE2GX WASHINGTON, DC Boot Your Search With Spring Christoph Strobl @stroblchristoph

Boot your Search with Spring

Embed Size (px)

Citation preview

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

SPRINGONE2GXWASHINGTON, DC

Boot Your Search With SpringChristoph Strobl

@stroblchristoph

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Agenda

2

1999 2004 2010 2014

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

The Thing with Search

3

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

The Thing with Search

• Simple Requirement

4

spring data

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

The Thing with Search

• Simple Requirement

• Complex Solution

5

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

The Thing with Search

• Simple Requirement

• Complex Solution

• Abstraction

6

{    fuzzy  :  {  text  :  "spring"  }}

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 7

“ …you need to understand at least one level of abstraction beneath the one at which you're working.

!Neal Ford

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 8

Spring Data

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data Modules

9

Commons

Neo4j Gemfire

JPA

Solr

Elasticsearch

REST

CassandraCouchbase

Redis

MongoDB

Communitymodules

Coremodules

Aerospike HazelcastCrateIncubating

KeyValue

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Release train

10

03/2015

Fowler

03/2013

Arora

09/2013

Babbage

02/2014

Codd

05/2014

Dijkstra

09/2014

Evans

09/2015

Gosling

imag

e so

urce

: wik

iped

ia C

C:B

Y11/2015

Hopper*

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data Release train BOM

<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-releasetrain</artifactId> <version>Gosling-RELEASE</version> <scope>import</scope> <type>pom</type> </dependency>

11

<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-rest-webmvc</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId>

<dependencyManagement> <dependencies>

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data

• Low level Templates

12

template.execute(new  DbCallback<CommandResult>()  {  

   @Override  

   public  CommandResult  doInDB(DB  db)  {  

       return  db.command(new  BasicDBObject("profile",  2));  

   }  

});

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data

• Low level Templates

• Repositories

13

interface  BlogPostRepo  extends  CrudRepository<BlogPost,  String>  {}

repository.save(blogPost);  

repository.findAll();  

repository.findOne("S2GX-­‐2015");  

repository.delete(blogPost);

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data

• Low level Templates

• Repositories

• Derived Queries

14

interface  BlogPostRepo  extends  CrudRepository<BlogPost,  String>  {

   List<BlogPost>  findByTitle(String  title);  

   Page<BlogPost>  findByTitle(String  title,  Pageable  page);  

   void  deleteByAuthor(Author  author);  

   Stream<BlogPost>  findBlogPostBy();    

}

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Let’s get started…

15

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Let’s get started…

• Schema

• Text Analysis

• Score / Boost

• Query vs. Filter Query

16

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 17

Spring Data

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Demo

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data MongoDB - Text Index

• Text Index

19

db.collection.ensureIndex(  

   {  title  :  "text",  content  :  "text",  categories  :  "text"}  

   

)

                                                                                                                   ,  

   {  weights  :  {  title  :  3,  content  :  2  }  }

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data MongoDB - Text Index

• Text Index

• Manual Index Creation

20

TextIndexDefinition  textIndex  =  new  TextIndexDefinitionBuilder()  

   

!!!

!    .onField("title",  3F)  

   .onField("content",  2F)  

   .onField("categories")  

   .build();  

operations.indexOps(BlogPost.class).ensureIndex(textIndex);

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data MongoDB - Text Index

• Text Index

• Manual Index Creation

• Automatic Index Creation

21

@Document  

class  BlogPost  {  

   @Id  String  id;  

   @TextIndexed(weight  =  3)  String  title;  

   @TextIndexed(weight  =  2)  String  content;  

   @TextIndexed  List<String>  categories;

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data MongoDB - Text Query

• Querying

22

TextCriteria  criteria  =  forDefaultLanguage().matching("release");  

TextQuery  query  =  query(criteria);  

!!!List<BlogPost>  blogPosts  =  operations.find(query,  BlogPost.class);

query.addCriteria(where("categories").in("Releases"));

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data MongoDB - Text Query

• Querying

• Scoring Results

23

TextCriteria  criteria  =  forDefaultLanguage().matching("release");  

TextQuery  query  =  query(criteria);  

!!!List<BlogPost>  blogPosts  =  operations.find(query,  BlogPost.class);

!query.setScoreFieldName("score");  

query.sortByScore();

@Document  

class  BlogPost  {  

   @Id  String  id;  

   //...  

   @ReadonlyProperty  Float  score;            

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data MongoDB - Text Query

• Querying

• Scoring Results

• Derived queries

24

interface  BlogPostRepo  extends  CrudRepository<BlogPost,  String>  {  

   

   List<BlogPost>  findAllBy(TextCriteria  criteria);  

!!}

@Document  

class  BlogPost  {  

   @Id  String  id;  

   //...  

   @TextScore  Float  score;                          

   List<BlogPost>  findAllByOrderByScoreDesc(TextCriteria  criteria);

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 25

Spring Data

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Solr - Schema

• Schema

26

<?xml version="1.0" encoding="UTF-8" ?><schema name="example" version="1.5"> <fields> <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="cat" type="string" indexed="true" stored="true" multiValued="true"/> <field name="features" type="text_general" indexed="true" stored="true" multiValued="true"/> <field name="weight" type="float" indexed="true" stored="true"/> <field name="price" type="float" indexed="true" stored="true"/> <field name="popularity" type="int" indexed="true" stored="true" /> <field ...

<fieldType name="text_general" class="solr.TextField" positionIncrementGa.. <analyzer type="index"> <tokenizer class="solr.StandardTokenizerFactory"/> <filter class="solr.StopFilterFactory" ignoreCase="true" words=“stop.. <filter class="solr.LowerCaseFilterFactory"/> </analyzer> <analyzer type="query"> <tokenizer class="solr.StandardTokenizerFactory"/> <filter class="solr.StopFilterFactory" ignoreCase="true" words=“stopwor.. <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" igno… <filter class="solr.LowerCaseFilterFactory"/> </analyzer> </fieldType>

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Solr - Schema

• Schema

• Managed Schema

27

<?xml version="1.0" encoding="UTF-8" ?><config> <schemaFactory class="ManagedIndexSchemaFactory"> <bool name="mutable">true</bool> <str name="managedSchemaResourceName">managed-schema</str> </schemaFactory> <...

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Solr - Full Text Search

• Requires a capture all field

28

!<field  name="_text_"  type="text_general"  indexed="true"  stored="false"  multiValued="true"/> <copyField  source="*"  dest="_text_"/>

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Just A Simple Solr Query

29

!    String  queryString  =  "name:"  +  ClientUtils.escapeQueryChars(name)  +      "  OR  description:"  +  ClientUtils.escapeQueryChars(description);  

   try  {  

       SolrQuery  query  =  new  SolrQuery(queryString);        query.setStart(0).setRows(0);  

       QueryResponse  response  =  solrClient.query(query);  

       long  totalValues  =  response.getResults().getNumFound();        query.setRows(totalValues);  

       return  solrClient.query(query).getBeans(Product.class);    }  catch  (Exception  e)  {        throw  ExceptionTranslator.translate(e);    }    return  Collections.emptyList();}

public  List<Product>  findByNameOrDescription(String  name,  String  description)  {

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Demo

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data Solr

• Query Time Boosting

31

!List<Product>  findTop10ByNameOrDescription(@Boost(2)  String  name,                                                                                        String  description);

@Document  

class  Product  {  

   @Id  String  id;  

   //...  

   @Score  Float  score;    

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data Solr

• Query Time Boosting

• Result Highlighting

32

@Highlight(fragsize  =  20,  snipplets  =  3)  

HighlightPage<Product>  findByDescription(String  description,  Pageable  page);

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data Solr

• Query Time Boosting

• Result Highlighting

• Schema API

33

class  Product  {  

   @Id  String  id;  

   @Indexed(type  =  "text_general")  String  name;  

   @Indexed(name  =  "cat",  type  =  "string")  List<String>  category;  

   @Indexed  boolean  inStock;  

}

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 34

Spring Data

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data Elasticsearch

• Indexing

35

@Document(indexName  =  "publications",  type  =  "book",  shards  =  1,  ...  

class  Book  {  

   @Id  String  id;  

!!!

!!                                

   PUT  /publications/book/1  

   {  

       "title":  "Wheel  of  Time",  

       ...  

   }

index typeid

@Document(indexName  =  "publications",  type  =  "article",  shards  =  1,  ...  

class  Article  {  

   @Id  String  id;

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data Elasticsearch

• Indexing

• Type Mapping

36

class  Article  {  

   @Id  String  id;  

   String  name;  

   @Field(format  =  DateFormat.date,  type=Date)  String  date;  

   @GeoPointField  String  location  

   @MultiField(mainField  =  @Field(type  =  String,  index  =  analyzed),                            otherFields  =  {@NestedField(dotSuffix  =  "sort",  indexAnalyzer  =  "keyword"    List<String>  authors;  

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data Elasticsearch

• Indexing

• Type Mapping

• Search API

37

CriteriaQuey  cq  =  new  CriteriaQuery(where("location").within(…

!!!!

SearchQuery  sq  =  new  NativeSearchQueryBuilder().withQuery(matchAllQuery())  

   .withFilter(boolFilter().must(termFilter("title",  "spring"))).build();

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Demo

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data Elasticsearch

• Facets

39

SearchQuery  query  =  new  NativeSearchQueryBuilder()    .withQuery(matchAllQuery())    .withFacet(new  TermFacetRequestBuilder("categoriesFacet")        .allTerms()        .fields("categories")        .descCount());  

FacetPage<Article>  page  =  template.queryForPage(query,  Article.class);

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring Data Elasticsearch

• Facets  

• Aggregation

40

SearchQuery  query  =  new  NativeSearchQueryBuilder()    .withQuery(matchAllQuery())    .withSearchType(SearchType.COUNT)    .withTypes("article")    .addAggregation(terms("subjects").field("subject"))    .build()  

Aggregations  aggregations  =  template.queryForPage(query,    response  -­‐>  response.getAggregations());

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Where’s the code?

41

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 42

Learn More. Stay Connected.

@springcentral Spring.io/video

projects.spring.io/spring-data/

github.com/spring-projects/spring-data-examples !