Post on 15-Jan-2017
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 !