Extensive writeup: http://project-a.github.io/on-site-search-design-patterns-for-e-commerce/
How can customers find the products that are relevant to what they are searching for? We will show in quite some detail how to set up Elasticsearch and how to represent documents so that:
* a customer can easily find what he wants by clicking through the category tree and applying filters (faceted navigation)
* relevant products can be found through a full text search (with optionally more filters applied to drill down the results)
* the right search results show up as suggestions when text is entered into the search box (completion)
* an alternative search result is shown when a term is misspelled (spell-checking)
Furthermore, we will introduce a technique for sorting search results that ranks products higher:
that are most relevant for the search
* with better past performance (revenue, clicks, click trough rate, etc.)
* with better expected customer experience (delivery speed, product quality)
And finally, we will illustrate how to personalize search experience along the example of dynamic pricing and discuss some other best practices.
The examples will come from Contorion, an online store for industrial and trade supply that sees on-site search as a major driver of its business. Please note that all the examples work in Elasticsearch 1.x and that some queries will look different in Elasticsearch 2.x, but the main concepts will still hold.
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
On-site search design patterns for e-commerce: schema structure, data driven ranking & more
1. 1 / 19
On-site search design patterns for e-commerce:
schema structure, data driven ranking & more
Dr. Martin Loetzsch, Project A Ventures
Krešimir Slugan, Contorion
https://goo.gl/xJr9Jshttp://project-a.github.io/on-site-search-design-patterns-for-e-commerce/
3. ! ‣
A naive product centric approach
2 / 19https://goo.gl/xJr9Js
‣Don’t do this!
{
"name": "Fäustel DIN6475 2000g Eschenstiel FORTIS",
"staple-name": "Fortis Fäustel, mit Eschen-Stiel",
"description": "Fäustel DIN 6475<br><br>Stahlgeschmiedet, Kopf schwarz
lackiert, Bahnen poliert, doppelt geschweifter Eschenstiel mit ozeanblau
lackiertem Handende. SP11968 SP11968",
"preview_image": "faeustel-din6475-2000g-eschenstiel-fortis-21049292-0-
JlHR5nOi-l.jpg",
"categories": [
"Fäustel",
"Handwerkzeug",
"Hammer",
"Fäustel"
],
"final_gross_price": 1149,
"final_net_price": 1003,
"url": "/handwerkzeug/fortis-faeustel-mit-eschen-stiel-SP11968",
"manufacturer": "Fortis",
"hammer_weight": 2000
}
‣ What are the attributes of your documents?
4. ! ‣
A naive product centric approach
2 / 19https://goo.gl/xJr9Js
‣Don’t do this!
‣ Huge complexity in schema design and query generation
• Queries need to explicitly list the attributes they want to operate on
• Difficult to use the same attribute in different operations
• Whenever new attributes appear, the schema needs to be extended
{
"name": "Fäustel DIN6475 2000g Eschenstiel FORTIS",
"staple-name": "Fortis Fäustel, mit Eschen-Stiel",
"description": "Fäustel DIN 6475<br><br>Stahlgeschmiedet, Kopf schwarz
lackiert, Bahnen poliert, doppelt geschweifter Eschenstiel mit ozeanblau
lackiertem Handende. SP11968 SP11968",
"preview_image": "faeustel-din6475-2000g-eschenstiel-fortis-21049292-0-
JlHR5nOi-l.jpg",
"categories": [
"Fäustel",
"Handwerkzeug",
"Hammer",
"Fäustel"
],
"final_gross_price": 1149,
"final_net_price": 1003,
"url": "/handwerkzeug/fortis-faeustel-mit-eschen-stiel-SP11968",
"manufacturer": "Fortis",
"hammer_weight": 2000
}
‣ What are the attributes of your documents?
5. ! ‣
A naive product centric approach
2 / 19https://goo.gl/xJr9Js
‣Don’t do this!
‣ Huge complexity in schema design and query generation
• Queries need to explicitly list the attributes they want to operate on
• Difficult to use the same attribute in different operations
• Whenever new attributes appear, the schema needs to be extended
‣ Full potential of data is usually not used
{
"name": "Fäustel DIN6475 2000g Eschenstiel FORTIS",
"staple-name": "Fortis Fäustel, mit Eschen-Stiel",
"description": "Fäustel DIN 6475<br><br>Stahlgeschmiedet, Kopf schwarz
lackiert, Bahnen poliert, doppelt geschweifter Eschenstiel mit ozeanblau
lackiertem Handende. SP11968 SP11968",
"preview_image": "faeustel-din6475-2000g-eschenstiel-fortis-21049292-0-
JlHR5nOi-l.jpg",
"categories": [
"Fäustel",
"Handwerkzeug",
"Hammer",
"Fäustel"
],
"final_gross_price": 1149,
"final_net_price": 1003,
"url": "/handwerkzeug/fortis-faeustel-mit-eschen-stiel-SP11968",
"manufacturer": "Fortis",
"hammer_weight": 2000
}
‣ What are the attributes of your documents?
6. ! ‣
A naive product centric approach
2 / 19https://goo.gl/xJr9Js
‣Don’t do this!
‣ Huge complexity in schema design and query generation
• Queries need to explicitly list the attributes they want to operate on
• Difficult to use the same attribute in different operations
• Whenever new attributes appear, the schema needs to be extended
‣ Full potential of data is usually not used
‣ Your search shouldn’t need to know that there is such a thing
as the weight of a hammer
{
"name": "Fäustel DIN6475 2000g Eschenstiel FORTIS",
"staple-name": "Fortis Fäustel, mit Eschen-Stiel",
"description": "Fäustel DIN 6475<br><br>Stahlgeschmiedet, Kopf schwarz
lackiert, Bahnen poliert, doppelt geschweifter Eschenstiel mit ozeanblau
lackiertem Handende. SP11968 SP11968",
"preview_image": "faeustel-din6475-2000g-eschenstiel-fortis-21049292-0-
JlHR5nOi-l.jpg",
"categories": [
"Fäustel",
"Handwerkzeug",
"Hammer",
"Fäustel"
],
"final_gross_price": 1149,
"final_net_price": 1003,
"url": "/handwerkzeug/fortis-faeustel-mit-eschen-stiel-SP11968",
"manufacturer": "Fortis",
"hammer_weight": 2000
}
‣ What are the attributes of your documents?
7. {
"type": "staple",
"search_result_data": {
"sku": "SP11968",
"name": "Fortis Fäustel, mit Eschen-Stiel",
"preview_image": "faeustel-din6475-2000g-eschenstiel-fortis-21049292-0-
JlHR5nOi-l.jpg",
"number_of_products": "4",
"final_gross_price": "822",
"final_net_price": "691",
"base_gross_price": null,
"base_price_unit": null,
"url": "/handwerkzeug/fortis-faeustel-mit-eschen-stiel-SP11968"
},
"search_data": [
{
"full_text": " 21049289 4317784792714 04317784792714 Fäustel DIN
6475<br><br>Stahlgeschmiedet, Kopf schwarz lackiert, Bahnen poliert, doppelt
geschweifter Eschenstiel mit ozeanblau lackiertem Handende. SP11968 SP11968",
"full_text_boosted": " Fortis Fäustel DIN6475 1000g Eschenstiel FORTIS
1000 Fäustel Handwerkzeug Hammer Fäustel Fortis Fäustel, mit Eschen-Stiel
Fortis Fäustel, mit Eschen-Stiel",
"string_facet": [
{
"facet-name": "manufacturer",
"facet-value": "Fortis"
},
{
"facet-name": "hammer_weight",
"facet-value": "1000"
}
],
"number_facet": [
{
"facet-name": "final_gross_price",
"facet-value": 822
}
]
},
{
"full_text": " 21049290 4317784792721 04317784792721 Fäustel DIN
Usage driven schema & document structure
‣ How do you want to use the attributes of your documents? ‣
3 / 19https://goo.gl/xJr9Js
‣Do this!
8. {
"type": "staple",
"search_result_data": {
"sku": "SP11968",
"name": "Fortis Fäustel, mit Eschen-Stiel",
"preview_image": "faeustel-din6475-2000g-eschenstiel-fortis-21049292-0-
JlHR5nOi-l.jpg",
"number_of_products": "4",
"final_gross_price": "822",
"final_net_price": "691",
"base_gross_price": null,
"base_price_unit": null,
"url": "/handwerkzeug/fortis-faeustel-mit-eschen-stiel-SP11968"
},
"search_data": [
{
"full_text": " 21049289 4317784792714 04317784792714 Fäustel DIN
6475<br><br>Stahlgeschmiedet, Kopf schwarz lackiert, Bahnen poliert, doppelt
geschweifter Eschenstiel mit ozeanblau lackiertem Handende. SP11968 SP11968",
"full_text_boosted": " Fortis Fäustel DIN6475 1000g Eschenstiel FORTIS
1000 Fäustel Handwerkzeug Hammer Fäustel Fortis Fäustel, mit Eschen-Stiel
Fortis Fäustel, mit Eschen-Stiel",
"string_facet": [
{
"facet-name": "manufacturer",
"facet-value": "Fortis"
},
{
"facet-name": "hammer_weight",
"facet-value": "1000"
}
],
"number_facet": [
{
"facet-name": "final_gross_price",
"facet-value": 822
}
]
},
{
"full_text": " 21049290 4317784792721 04317784792721 Fäustel DIN
Usage driven schema & document structure
‣ How do you want to use the attributes of your documents? ‣
3 / 19https://goo.gl/xJr9Js
‣Do this!
search result rendering
9. {
"type": "staple",
"search_result_data": {
"sku": "SP11968",
"name": "Fortis Fäustel, mit Eschen-Stiel",
"preview_image": "faeustel-din6475-2000g-eschenstiel-fortis-21049292-0-
JlHR5nOi-l.jpg",
"number_of_products": "4",
"final_gross_price": "822",
"final_net_price": "691",
"base_gross_price": null,
"base_price_unit": null,
"url": "/handwerkzeug/fortis-faeustel-mit-eschen-stiel-SP11968"
},
"search_data": [
{
"full_text": " 21049289 4317784792714 04317784792714 Fäustel DIN
6475<br><br>Stahlgeschmiedet, Kopf schwarz lackiert, Bahnen poliert, doppelt
geschweifter Eschenstiel mit ozeanblau lackiertem Handende. SP11968 SP11968",
"full_text_boosted": " Fortis Fäustel DIN6475 1000g Eschenstiel FORTIS
1000 Fäustel Handwerkzeug Hammer Fäustel Fortis Fäustel, mit Eschen-Stiel
Fortis Fäustel, mit Eschen-Stiel",
"string_facet": [
{
"facet-name": "manufacturer",
"facet-value": "Fortis"
},
{
"facet-name": "hammer_weight",
"facet-value": "1000"
}
],
"number_facet": [
{
"facet-name": "final_gross_price",
"facet-value": 822
}
]
},
{
"full_text": " 21049290 4317784792721 04317784792721 Fäustel DIN
Usage driven schema & document structure
‣ How do you want to use the attributes of your documents? ‣
3 / 19https://goo.gl/xJr9Js
‣Do this!
full-text search
19. Faceted navigation: the standard way
‣ Put all filterable attributes in unanalyzed document field: ‣
5 / 19https://goo.gl/xJr9Js
‣Does not scale to open-ended number of facets
"string_facets" : {
"manufacturer": "Fortis",
"hammer_weight": "2000",
"hammer_color": "Red"
}
20. Faceted navigation: the standard way
‣ Put all filterable attributes in unanalyzed document field: ‣
5 / 19https://goo.gl/xJr9Js
‣Does not scale to open-ended number of facets
"string_facets" : {
"manufacturer": "Fortis",
"hammer_weight": "2000",
"hammer_color": "Red"
}
"aggregations": {
"facet_manufacturer": {
"terms": {
"field": "string_facets.manufacturer"
}
},
"facet_hammer_weight": {
"terms": {
"field": "string_facets.hammer_weight"
}
},
"facet_hammer_color": {
"terms": {
"field": "string_facets.hammer_color"
}
}
}
‣ Explicitly list all facets in the query:
21. ! ‣
Generic faceted navigation
/ 19https://goo.gl/xJr9Js
‣Nicely scales to thousands of facets
‣ Put facet names as values in
documents:
"string_facets": [
{
"facet-name": "manufacturer",
"facet-value": "Fortis"
},
{
"facet-name": "hammer_weight",
"facet-value": "2000"
},
{
"facet-name": "hammer_color",
"facet-value": "Red"
}
]
6
22. ! ‣
Generic faceted navigation
/ 19https://goo.gl/xJr9Js
‣Nicely scales to thousands of facets
‣ Put facet names as values in
documents:
"string_facets": [
{
"facet-name": "manufacturer",
"facet-value": "Fortis"
},
{
"facet-name": "hammer_weight",
"facet-value": "2000"
},
{
"facet-name": "hammer_color",
"facet-value": "Red"
}
]
‣ Mark string_facets field as “nested”
in document:
"string_facets": {
"type": "nested",
"properties": {
"facet-name": {
"type": "string",
"index": "not_analyzed"
},
"facet-value": {
"type": "string",
"index": "not_analyzed"
}
}
}
6
28. Text analysis
‣ Pre-built Elasticsearch analyzers work, but won’t give the best user experience
8 / 19https://goo.gl/xJr9Js
‣Invest time in in building proper text analysis chains
29. Text analysis
‣ Pre-built Elasticsearch analyzers work, but won’t give the best user experience
8 / 19https://goo.gl/xJr9Js
‣Invest time in in building proper text analysis chains
Stiel für Schonhammer 800g
30. Text analysis
‣ Pre-built Elasticsearch analyzers work, but won’t give the best user experience
8 / 19https://goo.gl/xJr9Js
‣Invest time in in building proper text analysis chains
Stiel für Schonhammer 800g
Stiel für Schonhammer 800g
Whitespace tokenizer
31. Text analysis
‣ Pre-built Elasticsearch analyzers work, but won’t give the best user experience
8 / 19https://goo.gl/xJr9Js
‣Invest time in in building proper text analysis chains
Stiel für Schonhammer 800g
Stiel für Schonhammer 800g
Whitespace tokenizer
Stiel für Schonhammer 800g 800 g
Word-delimiter filter
32. Text analysis
‣ Pre-built Elasticsearch analyzers work, but won’t give the best user experience
8 / 19https://goo.gl/xJr9Js
‣Invest time in in building proper text analysis chains
Stiel für Schonhammer 800g
Stiel für Schonhammer 800g
Whitespace tokenizer
Stiel für Schonhammer 800g 800 g
Word-delimiter filter
stiel für schonhammer 800g 800 g
Lowercase filter
33. Text analysis
‣ Pre-built Elasticsearch analyzers work, but won’t give the best user experience
8 / 19https://goo.gl/xJr9Js
‣Invest time in in building proper text analysis chains
Stiel für Schonhammer 800g
Stiel für Schonhammer 800g
Whitespace tokenizer
Stiel für Schonhammer 800g 800 g
Word-delimiter filter
stiel für schonhammer 800g 800 g
Lowercase filter
stiel für schonhammer plastikhammer 800g 800 g
Synonym filter
34. Text analysis
‣ Pre-built Elasticsearch analyzers work, but won’t give the best user experience
8 / 19https://goo.gl/xJr9Js
‣Invest time in in building proper text analysis chains
Stiel für Schonhammer 800g
Stiel für Schonhammer 800g
Whitespace tokenizer
Stiel für Schonhammer 800g 800 g
Word-delimiter filter
stiel für schonhammer 800g 800 g
Lowercase filter
stiel für schonhammer plastikhammer 800g 800 g
Synonym filter
stiel für schonhammer schon hammer plastikhammer plastik hammer 800g 800 g
Decompounder filter
35. Text analysis
‣ Pre-built Elasticsearch analyzers work, but won’t give the best user experience
8 / 19https://goo.gl/xJr9Js
‣Invest time in in building proper text analysis chains
Stiel für Schonhammer 800g
Stiel für Schonhammer 800g
Whitespace tokenizer
Stiel für Schonhammer 800g 800 g
Word-delimiter filter
stiel für schonhammer 800g 800 g
Lowercase filter
stiel für schonhammer plastikhammer 800g 800 g
Synonym filter
stiel für schonhammer schon hammer plastikhammer plastik hammer 800g 800 g
Decompounder filter
stiel fur schonhammer schon hammer plastikhammer plastik hammer 800g 800 g
German normalization filter
36. Text analysis
‣ Pre-built Elasticsearch analyzers work, but won’t give the best user experience
8 / 19https://goo.gl/xJr9Js
‣Invest time in in building proper text analysis chains
Stiel für Schonhammer 800g
Stiel für Schonhammer 800g
Whitespace tokenizer
Stiel für Schonhammer 800g 800 g
Word-delimiter filter
stiel für schonhammer 800g 800 g
Lowercase filter
stiel für schonhammer plastikhammer 800g 800 g
Synonym filter
stiel für schonhammer schon hammer plastikhammer plastik hammer 800g 800 g
Decompounder filter
stiel fur schonhammer schon hammer plastikhammer plastik hammer 800g 800 g
German normalization filter
stiel fur schonhamm scho hamm plastikhamm plastik hamm 800g 800 g
German stemmer filter
37. Text relevance
‣ Split searchable text by importance in documents:
9 / 19https://goo.gl/xJr9Js
‣Improve relevance by combining multiple analyzers
"full_text": "21049291 4317784792738 Fäustel DIN
6475<br><br>Stahlgeschmiedet, Kopf schwarz lackiert, Bahnen poliert,
doppelt geschweifter Eschenstiel mit ozeanblau lackiertem Handende
SP11968",
"full_text_boosted": "Fortis Fäustel DIN6475 2000g Eschenstiel FORTIS
2000 Fäustel Handwerkzeug Hammer Fäustel Fortis Fäustel, mit Eschen-
Stiel Fortis Fäustel, mit Eschen-Stiel"
38. Text relevance
‣ Split searchable text by importance in documents:
9 / 19https://goo.gl/xJr9Js
‣Improve relevance by combining multiple analyzers
"full_text": "21049291 4317784792738 Fäustel DIN
6475<br><br>Stahlgeschmiedet, Kopf schwarz lackiert, Bahnen poliert,
doppelt geschweifter Eschenstiel mit ozeanblau lackiertem Handende
SP11968",
"full_text_boosted": "Fortis Fäustel DIN6475 2000g Eschenstiel FORTIS
2000 Fäustel Handwerkzeug Hammer Fäustel Fortis Fäustel, mit Eschen-
Stiel Fortis Fäustel, mit Eschen-Stiel"
"properties": {
"full_text": {
"type": "string",
"index_analyzer": "full_text_index_analyzer",
"search_analyzer": "full_text_search_analyzer",
"fields": {
"no-decompound": {
"type": "string",
"index_analyzer": "full_text_index_analyzer_no_decompound",
"search_analyzer": "full_text_search_analyzer_no_decompound"
},
"no-stem": {
"type": "string",
"index_analyzer": "full_text_index_analyzer_no_stem",
"search_analyzer": "full_text_search_analyzer_no_stem"
}
}
}
}
‣ Apply multiple analyzers to full-text fields in mapping:
44. Data driven ranking
10 / 19https://goo.gl/xJr9Js
! ‣
Result order
‣Align formula with business goals
45. Data driven ranking
10 / 19https://goo.gl/xJr9Js
! ‣‣ Add normalized scores to document that each reflect a
heuristic what a “good” result is:
"scores": {
"top_seller": 0.91,
"pdp_impressions": 0.38,
"sale_impressions_rate": 0.68,
"data_quality": 0.87,
"delivery_speed": 0.85,
"random": 0.75,
"stock": 1
}
Result order
‣Align formula with business goals
most scores left out due to their sensitive nature
46. Data driven ranking
10 / 19https://goo.gl/xJr9Js
! ‣‣ Add normalized scores to document that each reflect a
heuristic what a “good” result is:
"scores": {
"top_seller": 0.91,
"pdp_impressions": 0.38,
"sale_impressions_rate": 0.68,
"data_quality": 0.87,
"delivery_speed": 0.85,
"random": 0.75,
"stock": 1
}
‣ Concrete scores depend on business
Result order
‣Align formula with business goals
most scores left out due to their sensitive nature
47. Data driven ranking
10 / 19https://goo.gl/xJr9Js
! ‣‣ Add normalized scores to document that each reflect a
heuristic what a “good” result is:
"scores": {
"top_seller": 0.91,
"pdp_impressions": 0.38,
"sale_impressions_rate": 0.68,
"data_quality": 0.87,
"delivery_speed": 0.85,
"random": 0.75,
"stock": 1
}
‣ Concrete scores depend on business
"query": {
"filtered": {
"query": {
"function_score": {
"score_mode": "first",
"boost_mode": "replace",
"query": {},
"functions": [
{
"script_score": {
"script": "
(1 + _score ** 0.5)
* doc['scores.stock'].value
* (0.1 * doc['scores.random'].value
+ 0.3 * doc['scores.top_seller'].value
+ 0.1 * doc['scores.pdp_impressions'].value
+ 0.2 * doc['scores.sale_impressions_rate'].value
+ 0.1 * doc['scores.data_quality'].value
+ 0.3 * doc['scores.delivery_speed'].value)"
}
}
]
}
}
}
}
‣ Combine scores through algebraic formula in query:
(actual weights replaced by random values)
‣Align formula with business goals
most scores left out due to their sensitive nature
48. ‣ Example I: expected margin
Normalized, evenly-distributed scores I
11 / 19https://goo.gl/xJr9Js
‣Look at the distribution of a measure across all products
-0.2 0.0 0.2 0.4 0.6 0.8 1.0
05000100001500020000
0.00.51.0
0.5+atan((x−0.1)0.05)π
computation of score expected_margin
#products
x = expected_margin
data from 2014
49. ‣ Example I: expected margin
Normalized, evenly-distributed scores I
11 / 19https://goo.gl/xJr9Js
‣Look at the distribution of a measure across all products
-0.2 0.0 0.2 0.4 0.6 0.8 1.0
05000100001500020000
0.00.51.0
0.5+atan((x−0.1)0.05)π
computation of score expected_margin
#products
x = expected_margin
data from 2014
distribution of the expected margin across all products
50. ‣ Example I: expected margin
Normalized, evenly-distributed scores I
11 / 19https://goo.gl/xJr9Js
‣Look at the distribution of a measure across all products
-0.2 0.0 0.2 0.4 0.6 0.8 1.0
05000100001500020000
0.00.51.0
0.5+atan((x−0.1)0.05)π
computation of score expected_margin
#products
x = expected_margin
data from 2014
distribution of the expected margin across all products
score function
51. ‣ Example I: expected margin
Normalized, evenly-distributed scores I
11 / 19https://goo.gl/xJr9Js
‣Look at the distribution of a measure across all products
-0.2 0.0 0.2 0.4 0.6 0.8 1.0
05000100001500020000
0.00.51.0
0.5+atan((x−0.1)0.05)π
computation of score expected_margin
#products
x = expected_margin
data from 2014
distribution of the expected margin across all products
mean
stdev
score function
52. ‣ Example II: expected time of delivery
Normalized, evenly-distributed scores II
12 / 19https://goo.gl/xJr9Js
‣Finding meaningful scores is a requirement for a good ranking
100 200 300 400
020000400006000080000
0.00.51.0
0.5−atan((x−48)12)π
computation of score delivery_speed
#products
x = delivery_time
data from 2014
53. ‣ Example II: expected time of delivery
Normalized, evenly-distributed scores II
12 / 19https://goo.gl/xJr9Js
‣Finding meaningful scores is a requirement for a good ranking
100 200 300 400
020000400006000080000
0.00.51.0
0.5−atan((x−48)12)π
computation of score delivery_speed
#products
x = delivery_time
48 hours = neutral → 0.5
data from 2014
54. ‣ Example II: expected time of delivery
Normalized, evenly-distributed scores II
12 / 19https://goo.gl/xJr9Js
‣Finding meaningful scores is a requirement for a good ranking
100 200 300 400
020000400006000080000
0.00.51.0
0.5−atan((x−48)12)π
computation of score delivery_speed
#products
x = delivery_time
48 hours = neutral → 0.5
60 hours = acceptable → 0.25
data from 2014
55. ‣ Example II: expected time of delivery
Normalized, evenly-distributed scores II
12 / 19https://goo.gl/xJr9Js
‣Finding meaningful scores is a requirement for a good ranking
100 200 300 400
020000400006000080000
0.00.51.0
0.5−atan((x−48)12)π
computation of score delivery_speed
#products
x = delivery_time
48 hours = neutral → 0.5
60 hours = acceptable → 0.25
bad
data from 2014
56. ‣ Example II: expected time of delivery
Normalized, evenly-distributed scores II
12 / 19https://goo.gl/xJr9Js
‣Finding meaningful scores is a requirement for a good ranking
100 200 300 400
020000400006000080000
0.00.51.0
0.5−atan((x−48)12)π
computation of score delivery_speed
#products
x = delivery_time
48 hours = neutral → 0.5
good
60 hours = acceptable → 0.25
bad
data from 2014
58. Multi-term auto-completion
! ‣
13 / 19https://goo.gl/xJr9Js
‣Allow users to drill down to results by combining multiple attributes
"completion_terms": [
"Fortis",
"1000",
"1250",
"1500",
"2000",
"Fäustel",
"Handwerkzeug",
"Hammer"
]
‣ Put all terms to complete on in document
59. Multi-term auto-completion
! ‣
13 / 19https://goo.gl/xJr9Js
‣Allow users to drill down to results by combining multiple attributes
"completion_terms": [
"Fortis",
"1000",
"1250",
"1500",
"2000",
"Fäustel",
"Handwerkzeug",
"Hammer"
]
‣ Put all terms to complete on in document
"completion_terms": {
"type": "string",
"analyzer": "completion_analyzer"
}
‣ Leave terms more or less un-altered in mapping
60. Multi-term auto-completion
! ‣
13 / 19https://goo.gl/xJr9Js
‣Allow users to drill down to results by combining multiple attributes
"completion_terms": [
"Fortis",
"1000",
"1250",
"1500",
"2000",
"Fäustel",
"Handwerkzeug",
"Hammer"
]
‣ Put all terms to complete on in document
"completion_terms": {
"type": "string",
"analyzer": "completion_analyzer"
}
‣ Leave terms more or less un-altered in mapping
"aggs": {
"autocomplete": {
"terms": {
"field": "completion_terms",
"size": 100
}
}
}
‣ Filter by input, aggregate by terms in query
62. Simple spelling suggestions
14 / 19https://goo.gl/xJr9Js
‣Very easy to build, and customers expect it
! ‣
"suggestion_terms": [
"Fortis Fäustel, mit Eschen-Stiel"
]
‣ Put high quality suggestion terms in document:
63. Simple spelling suggestions
14 / 19https://goo.gl/xJr9Js
‣Very easy to build, and customers expect it
! ‣
‣ Apply a simple analyzer that that splits text by
whitespace and that lowercases it:
"suggestion_terms" : {
"type" : "string",
"analyzer" : "term_suggestion_analyzer",
}
"suggestion_terms": [
"Fortis Fäustel, mit Eschen-Stiel"
]
‣ Put high quality suggestion terms in document:
64. Simple spelling suggestions
14 / 19https://goo.gl/xJr9Js
‣Very easy to build, and customers expect it
! ‣
‣ Apply a simple analyzer that that splits text by
whitespace and that lowercases it:
"suggestion_terms" : {
"type" : "string",
"analyzer" : "term_suggestion_analyzer",
}
"suggestion_terms": [
"Fortis Fäustel, mit Eschen-Stiel"
]
‣ Put high quality suggestion terms in document:
‣ Look for most similar term by distance in query:
"suggest": {
"spelling-suggestion": {
"text": "hammmer",
"term": {
"field": "suggestion_terms",
"size": 1
}
}
}
65. Personalization: dynamic pricing
‣ User specific discounts per product or category
15 / 19https://goo.gl/xJr9Js
‣Scripts can be used for many other types of user specific personalisations
"query": {
"script_fields": {
"final_gross_price_discount": {
"script": “
if (fixed_prices && fixed_prices[doc['sku'].value]) {
return fixed_prices[doc['sku'].value]
}
if(!discounts) {
return
};
def discount = 0;
for (String i : doc['discount_categories']) {
if(discounts[i] && discounts[i].value > discount) {
discount = discounts[i].value
}
}
if (discount > 0 && doc['prices.discount_gross_price_level_' + discount].value) {
return doc['prices.discount_gross_price_level_' + discount].value
}",
"params": {
"discounts": {
"47": 5,
"453": 2,
"305": 7
},
"fixed_prices": {
"210417044": 9999,
"128553": 100
}
}
}
}
}
66. Index pages, not products
‣ Usage driven schemas can be used for any kinds of
searchable documents
‣
16 / 19https://goo.gl/xJr9Js
‣Makes brands, categories, editorial content, etc. easily findable
{
"type": "cms-page",
"search_result_data": {
"id": "7",
"title": "Versandkosten | contorion.de",
"name": "Versandinformationen",
"url": "/versandkosten"
},
"search_data": {
"full_text_boosted": [
"Versandinformationen"
],
"full_text": [
"<p>Die Versandkosten innerhalb Deutschlands betragen
5,95€ pro Bestellung. Ab einem Warenwert von 50 € liefert
Contorion versandkostenfrei.</p><p>Contorion.de liefert im
Moment nur nach Deutschland.</p>"
]
}
}
67. Explicit attribute management
‣ Conscious decisions have to be made about how to use each attribute
‣ An explicit representation makes things more maintainable
17 / 19https://goo.gl/xJr9Js
‣Bonus points for providing an UI
attribute full text
full text
boosted
string
facet
number
facet
completion
terms
suggestion
terms
search
result data
description ✓
manufacturer ✓ ✓ ✓ ✓ ✓
name ✓ ✓ ✓ ✓
sku ✓ ✓
hammer_weight ✓ ✓ ✓
hammer_handle_length ✓ ✓
hammer_handle_material ✓ ✓ ✓
preview_image ✓
url ✓
68. Product management for search
‣ Best: concrete examples of how search should behave from a user perspective
18 / 19https://goo.gl/xJr9Js
‣If I search for a hammer, I want to find a hammer
search term issue / expected result dev comment
makita i would expect standard power tools on top (e.g., drilling machine), not a
jacket & a laser
Enhance WHF
akkuschrauber I would expect more search word suggestions, not just Akkuschrauber-Set PM: In specification
schleifscheibe no top sellers on top Add all categories, add popularity
score to category ranking
latt hammer should give back Latthammers first we might ne to recalibrate the
search a little bit
blindnietwerkzeug only gives back products called “Blindnietwerkzeug” but no Blindnietzange
or Blindnietmutter-Handgerät and so on
Please add Tokens to list
bohrmaschine
bosch
top categories should be the ones that actually have “Bohrmaschine” as
it’s name, not Bohrständer and stuff
fixed
tiefenmesschieber customers missing an “s” don’t get any results for TiefenmesSschieber very hard to fix
klopapier synonym for “Toilettenpapier” please create synonyms yourself
duebel doesn’t find products when “ä” is “ae” - that should happen for all umlaute fixed
Handwaschpaste doesn’t find category bug
69. Product management for search
‣ Best: concrete examples of how search should behave from a user perspective
18 / 19https://goo.gl/xJr9Js
‣If I search for a hammer, I want to find a hammer
search term issue / expected result dev comment
makita i would expect standard power tools on top (e.g., drilling machine), not a
jacket & a laser
Enhance WHF
akkuschrauber I would expect more search word suggestions, not just Akkuschrauber-Set PM: In specification
schleifscheibe no top sellers on top Add all categories, add popularity
score to category ranking
latt hammer should give back Latthammers first we might ne to recalibrate the
search a little bit
blindnietwerkzeug only gives back products called “Blindnietwerkzeug” but no Blindnietzange
or Blindnietmutter-Handgerät and so on
Please add Tokens to list
bohrmaschine
bosch
top categories should be the ones that actually have “Bohrmaschine” as
it’s name, not Bohrständer and stuff
fixed
tiefenmesschieber customers missing an “s” don’t get any results for TiefenmesSschieber very hard to fix
klopapier synonym for “Toilettenpapier” please create synonyms yourself
duebel doesn’t find products when “ä” is “ae” - that should happen for all umlaute fixed
Handwaschpaste doesn’t find category bug
70. Product management for search
‣ Best: concrete examples of how search should behave from a user perspective
18 / 19https://goo.gl/xJr9Js
‣If I search for a hammer, I want to find a hammer
search term issue / expected result dev comment
makita i would expect standard power tools on top (e.g., drilling machine), not a
jacket & a laser
Enhance WHF
akkuschrauber I would expect more search word suggestions, not just Akkuschrauber-Set PM: In specification
schleifscheibe no top sellers on top Add all categories, add popularity
score to category ranking
latt hammer should give back Latthammers first we might ne to recalibrate the
search a little bit
blindnietwerkzeug only gives back products called “Blindnietwerkzeug” but no Blindnietzange
or Blindnietmutter-Handgerät and so on
Please add Tokens to list
bohrmaschine
bosch
top categories should be the ones that actually have “Bohrmaschine” as
it’s name, not Bohrständer and stuff
fixed
tiefenmesschieber customers missing an “s” don’t get any results for TiefenmesSschieber very hard to fix
klopapier synonym for “Toilettenpapier” please create synonyms yourself
duebel doesn’t find products when “ä” is “ae” - that should happen for all umlaute fixed
Handwaschpaste doesn’t find category bug
71. Product management for search
‣ Best: concrete examples of how search should behave from a user perspective
18 / 19https://goo.gl/xJr9Js
‣If I search for a hammer, I want to find a hammer
search term issue / expected result dev comment
makita i would expect standard power tools on top (e.g., drilling machine), not a
jacket & a laser
Enhance WHF
akkuschrauber I would expect more search word suggestions, not just Akkuschrauber-Set PM: In specification
schleifscheibe no top sellers on top Add all categories, add popularity
score to category ranking
latt hammer should give back Latthammers first we might ne to recalibrate the
search a little bit
blindnietwerkzeug only gives back products called “Blindnietwerkzeug” but no Blindnietzange
or Blindnietmutter-Handgerät and so on
Please add Tokens to list
bohrmaschine
bosch
top categories should be the ones that actually have “Bohrmaschine” as
it’s name, not Bohrständer and stuff
fixed
tiefenmesschieber customers missing an “s” don’t get any results for TiefenmesSschieber very hard to fix
klopapier synonym for “Toilettenpapier” please create synonyms yourself
duebel doesn’t find products when “ä” is “ae” - that should happen for all umlaute fixed
Handwaschpaste doesn’t find category bug
72. ‣ Structure documents around the usage of attributes
‣ Index pages, not products
19 / 19https://goo.gl/xJr9Js
Conclusions
73. ‣ Structure documents around the usage of attributes
‣ Index pages, not products
19 / 19https://goo.gl/xJr9Js
https://goo.gl/xJr9Jshttp://project-a.github.io/on-site-search-design-patterns-for-e-commerce/
Conclusions
74. ‣ Structure documents around the usage of attributes
‣ Index pages, not products
19 / 19https://goo.gl/xJr9Js
‣Thank you !
https://goo.gl/xJr9Jshttp://project-a.github.io/on-site-search-design-patterns-for-e-commerce/
Conclusions