Search as main navigation

61
Search as main navigation

Transcript of Search as main navigation

Page 1: Search as main navigation

Search as main navigation

Page 2: Search as main navigation

Daniel Lienert• Scrum Master / Software Architect

@ punkt.de / Karlsruhe

• Neos Core Team Member

• @dlienert

Page 3: Search as main navigation

Sebastian Helzle• Product Owner

@ punkt.de / Karlsruhe

• Neos Core Team Member

• @sebobo

Page 4: Search as main navigation

Overview• Motivation to integrate a great search

• The basics

• Indexing

• Search

• Result rendering

• Live search

• Outlook

Page 5: Search as main navigation

Motivation

Page 6: Search as main navigation

„Increase user interaction“

Page 7: Search as main navigation

„Optimize real users workflows“

Page 8: Search as main navigation

„Different users different goals“

Page 9: Search as main navigation

„Choose the right tools“

Page 10: Search as main navigation

„Don’t build or sell Google 2.0“

Page 11: Search as main navigation

„Have an ongoing feedback loop“

Page 12: Search as main navigation

„Think about searchin the design process“

Page 13: Search as main navigation
Page 14: Search as main navigation
Page 15: Search as main navigation
Page 16: Search as main navigation
Page 17: Search as main navigation
Page 18: Search as main navigation

Glossary

Page 19: Search as main navigation

Glossary

• Terms & Phrases

Page 20: Search as main navigation

Glossary

• „Did you mean“

Page 21: Search as main navigation

Glossary

• Completions & Suggestions

Page 22: Search as main navigation

Glossary

• Aggregations & Facets

Page 23: Search as main navigation

Glossary

• Boosting & Weights

Page 24: Search as main navigation

Building Blocks

Page 25: Search as main navigation

ElasticsearchElasticsearch is an open source, distributed, scalable, document-oriented, RESTful, full text search engine with real-time search an analytics capabilities.

Based on Apache Lucene. Combines search and powerful analytics.

Provides a HTTP REST and a Java interface.

Page 26: Search as main navigation

Neos Content Repository

Flowpack.SearchPlugin

Neos.ContentRepository. Search

Flowpack.ElasticSearch.ContentRepositoryAdaptor

Flowpack.ElasticSearch

Page 27: Search as main navigation

Neos Content Repository

Flowpack.SearchPlugin

Neos.ContentRepository. Search

Flowpack.ElasticSearch.ContentRepositoryAdaptor

Flowpack.ElasticSearch

‣ The frontend plugin ‣ Search input and result rendering ‣ Soon: Controller for real-time autocompletion

and suggestions

Page 28: Search as main navigation

Neos Content Repository

Flowpack.SearchPlugin

Neos.ContentRepository. Search

Flowpack.ElasticSearch.ContentRepositoryAdaptor

Flowpack.ElasticSearch‣ Indexing of nodes to ES documents ‣ Compiles Eel statements into ES queries ‣ ES driver for versions 1.x and 2.x

Page 29: Search as main navigation

Flowpack.SearchPlugin

Neos Content Repository

Neos.ContentRepository. Search

Flowpack.ElasticSearch.ContentRepositoryAdaptor

Flowpack.ElasticSearch

‣ Provides the indexing EelHelper ‣ Provides an abstract search helper interface.

Page 30: Search as main navigation

Flowpack.SearchPlugin

Neos Content Repository

Neos.ContentRepository. Search

Flowpack.ElasticSearch.ContentRepositoryAdaptor

Flowpack.ElasticSearch

‣ Provides an API for using ES with Flow ‣ Low Level Interface to ES

Page 31: Search as main navigation

Start the Engine

Page 32: Search as main navigation

Preparation - InstallationStep 1: Install Elasticsearch

wget https://download.elastic.co/.../elasticsearch-2.4.0.zip

unzip elasticsearch-2.4.0.zip

elasticsearch-2.4.0/bin/elasticsearch

Page 33: Search as main navigation

Preparation - InstallationStep 2: Configure Elasticsearch

•script.inline: true

config/elasticsearch.yml:

Page 34: Search as main navigation

Indexing

Page 35: Search as main navigation

Basic Index Configuration• Configuration provider

• Neos CR Search package

• Elasticsearch CR Adaptor

• Flowpack Searchplugin

• Many use cases don’t need extra configuration

Page 36: Search as main navigation

Node Types• Package stack already provides many defaults

• Custom configurations can be added or extended

• Best practice

• Use mixins for common configurations

Page 37: Search as main navigation

Node Type indexing example

'PunktDe.Website:EmployeeElement': search: fulltext: isRoot: true label: '${String.cropAtWord(q(node).property(''name'') || … }’ superTypes: 'Neos.Neos:Content': true 'Flowpack.SearchPlugin:SuggestableMixin': true 'Flowpack.SearchPlugin:AutocompletableMixin': true …

Page 38: Search as main navigation

Node Type indexing example

'PunktDe.Website:EmployeeElement': search: fulltext: isRoot: true label: '${String.cropAtWord(q(node).property(''name'') || … }’ superTypes: 'Neos.Neos:Content': true 'Flowpack.SearchPlugin:SuggestableMixin': true 'Flowpack.SearchPlugin:AutocompletableMixin': true …

Page 39: Search as main navigation

Node Type indexing example'PunktDe.Website:EmployeeElement': … properties: '__suggestions': search: indexing: "${Flowpack.SearchPlugin.Suggestion.build(q(node).property('name') + …, node.identifier, FusionRendering.render(node, 'suggestion'), 100)}" '__completion': search: indexing: "${q(node).property('name')}" name: type: string search: fulltextExtractor: ${Indexing.extractInto('h1', value)}

Page 40: Search as main navigation

Node Type indexing example'PunktDe.Website:EmployeeElement': … properties: '__suggestions': search: indexing: "${Flowpack.SearchPlugin.Suggestion.build(q(node).property('name') + …, node.identifier, FusionRendering.render(node, 'suggestion'), 100)}" '__completion': search: indexing: "${q(node).property('name')}" name: type: string search: fulltextExtractor: ${Indexing.extractInto('h1', value)}

Page 41: Search as main navigation

Node Type indexing example'PunktDe.Website:EmployeeElement': … properties: '__suggestions': search: indexing: "${Flowpack.SearchPlugin.Suggestion.build(q(node).property('name') + …, node.identifier, FusionRendering.render(node, 'suggestion'), 100)}" '__completion': search: indexing: "${q(node).property('name')}" name: type: string search: fulltextExtractor: ${Indexing.extractInto('h1', value)}

Page 42: Search as main navigation

Indexing Assets

bin/plugin install elasticsearch/elasticsearch-mapper-attachments/2.1.7

• Requires the attachment type for Elasticsearch

• Included for Elasticsearch > 2.1

• For 1.7 you need to install the plugin separately

Page 43: Search as main navigation

Asset indexing configurationNeos: ContentRepository: Search: defaultConfigurationPerType: 'Neos\Media\Domain\Model\Asset': elasticSearchMapping: type: attachment include_in_all: true indexing: ${Indexing.indexAsset(value)}

'array<Neos\Media\Domain\Model\Asset>': elasticSearchMapping: type: attachment include_in_all: true indexing: ${Indexing.indexAsset(value)}

Page 44: Search as main navigation

Searching

Search

Page 45: Search as main navigation

Basic Search

Page 46: Search as main navigation

Basic Search

baseQuery = ${Search.query(site).fulltext(this.searchTerm)}

Page 47: Search as main navigation

•C

ase

Stu

dies

Blo

g Art

icle

s

Node Type Based Rendering•

Page

s

Page 48: Search as main navigation

Node Type Based Rendering

prototype(Neos.Neos:DocumentSearchResult) { }

prototype(Vendor.Site:CaseStudySearchResult) < prototype(Neos.Neos:DocumentSearchResult) { templatePath = resource://Vendor.Site/.../CaseStudySearchResult.html }

prototype(Vendor.Site:BlogPostSearchResult) < prototype(Neos.Neos:DocumentSearchResult) { templatePath = resource://Vendor.Site/.../BlogPostSearchResult.html }

Page 49: Search as main navigation

Facets #1

aggregateQuery = ${this.baseQuery .fieldBasedAggregation('types','_type')

.execute().getAggregations().types.buckets}

Page 50: Search as main navigation

Facets #2

<f:for each="{types}" as="type"> <li> <neos:link.node node="{searchPage}"

arguments="{'search' : ‚{searchTerm}‘, 'type': '{type.key}'}"> {type.key} ({type.doc_count}) </neos:link.node> </li> </f:for>

Page 51: Search as main navigation

Facets #3

baseQuery.@process { facets = ${value.queryFilter("term", {"_type": request.arguments.type})} }

Page 52: Search as main navigation

Highlighting

searchQuery.@process { highlight = ${value.highlight(300, 1)} }

Page 53: Search as main navigation

Did You Mean

didYouMean = ${SearchResult.didYouMean(this.searchQuery)}

Page 54: Search as main navigation

Live search

Page 55: Search as main navigation

Autocompletion• Offers possible word & phrase completions (like google)

• Helps when you’re unsure about spelling

• Very fast

• No correction

• Currently missing

• Doesn’t respect context (e.g. dimensions)

• No weighting

Page 56: Search as main navigation

Suggestions• Fuzzy search

• Respects search context (dimensions, workspaces, starting point)

• Slower if context is not cached (Solved in Searchplugin)

• Weighting

• Show alternative results

• Customizable payload during index time

• Type based suggestions

• Pre rendered output

• Direct linking

Page 57: Search as main navigation

The Future

Page 58: Search as main navigation

The future• Elasticsearch 5.x driver

• Support multiple indices (e.g. multi-site installations)

• Better support for language specialities

• Indexqueue

• Improved documentation and example library

Page 59: Search as main navigation

I also want to have a cool search• Checkout the Flowpack/Searchplugin package

• Post feedback & ideas

• on Github

• the guild-search Slack channel

• Use the SEO package and index metadata

• Treat internal search like external search (index property)

Page 60: Search as main navigation

Questions?

Page 61: Search as main navigation

Links• https://github.com/neos/typo3cr-search

• https://github.com/Flowpack/Flowpack.ElasticSearch.ContentRepositoryAdaptor

• https://github.com/Flowpack/Flowpack.SearchPlugin

• https://github.com/Flowpack/Flowpack.ElasticSearch