Skip to content

Instantly share code, notes, and snippets.

@davidbkemp
Last active May 3, 2023 14:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidbkemp/41d34fb888ebff49b8ea0047c3324770 to your computer and use it in GitHub Desktop.
Save davidbkemp/41d34fb888ebff49b8ea0047c3324770 to your computer and use it in GitHub Desktop.
Example of using Elasticsearch percolation to match a listing against saved searches
# Example listings definition
PUT /listings
{
"mappings": {
"properties": {
"description": {"type": "text", "analyzer": "english"},
"suburb": {"type": "keyword"},
"bedrooms": {"type": "integer"}
}
}
}
# Example listing
PUT /listings/_doc/abc123
{
"suburb": "Coburg VIC 3058",
"bedrooms": 1,
"description": "Above ground swimming pool. Spacious kitchen"
}
# Example search for a 1 to 3 beroom place in Coburg with a swimming pool
GET /listings/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"suburb": "Coburg VIC 3058"
}
},
{
"range": {"bedrooms": {"gte": 1, "lte": 3}}
},
{
"match_phrase": {
"description": "swim pool"
}
}
]
}
}
}
# Creat an index in which to save searches
# Note the field type of "percolator"
# Also note that we need to duplicate all the field definitions that are in the listings index
PUT /saved-searches
{
"mappings": {
"properties": {
"userId": {"type": "keyword"},
"savedSearchName": {"type": "keyword"},
"query": {"type": "percolator"},
"description": {"type": "text", "analyzer": "english"},
"suburb": {"type": "keyword"},
"bedrooms": {"type": "integer"}
}
}
}
# Saving some searches
PUT /saved-searches/_doc/1
{
"userId": "1234",
"savedSearchName": "My Coburg Search",
"query": {
"bool": {
"filter": [
{"term": {"suburb": "Coburg VIC 3058"}},
{"range": {"bedrooms": {"gte": 1, "lte": 3}}},
{"match_phrase": {"description": "swim pool"}} ]
}
}
}
PUT /saved-searches/_doc/2
{
"userId": "1234",
"savedSearchName": "My Brunswick Search",
"query": {
"bool": {
"filter": [
{"term": {"suburb": "Brunswick VIC 3056"}},
{"range": {"bedrooms": {"gte": 1, "lte": 3}}},
{"match_phrase": {"description": "swim pool"}} ]
}
}
}
# Using percolation to find searches that match a listing
GET /saved-searches/_search
{
"query": {
"percolate": {
"field": "query",
"document": {
"suburb": "Coburg VIC 3058",
"bedrooms": 2,
"description": "Large garden, swimming pool"
}
}
}
}
# What about surrounding suburb matches?
PUT /listings/_mappings
{
"properties": {
"description": {"type": "text", "analyzer": "english"},
"suburb": {"type": "keyword"},
"bedrooms": {"type": "integer"},
"surroundingSuburbs": {"type": "keyword"}
}
}
# Example listings with surrounding suburbs
PUT /listings/_doc/abc123
{
"suburb": "Coburg VIC 3058",
"bedrooms": 1,
"description": "Above ground swimming pool. Spacious kitchen",
"surroundingSuburbs": ["Brunswick VIC 3056", "Pascoe Vale 3044", "Preston VIC 3072", "Thornbury VIC 3071", "Coburg North VIC 3058"]
}
PUT /listings/_doc/def456
{
"suburb": "Brunswick VIC 3056",
"bedrooms": 1,
"description": "Modern kitchen, close to public transport",
"surroundingSuburbs": ["Coburg VIC 3058", "Parkville VIC 3052", "Thornbury VIC 3071", "Brunswick East VIC 3057"]
}
# Search Coburg and surrounds, but boost Coburg above others
GET /listings/_search
{
"query": {
"bool": {
"should": [
{
"constant_score": {
"filter": {
"term": {
"suburb": "Coburg VIC 3058"
}
},
"boost": 10
}
}
],
"filter": [
{
"bool": {
"should": [
{
"term": {
"suburb": "Coburg VIC 3058"
}
},
{
"term": {
"surroundingSuburbs": "Coburg VIC 3058"
}
}
]
}
}
]
}
}
}
# Saved searches with surrounding suburbs
PUT /saved-searches/_mapping
{
"properties": {
"userId": {"type": "keyword"},
"savedSearchName": {"type": "keyword"},
"query": {"type": "percolator"},
"description": {"type": "text", "analyzer": "english"},
"suburb": {"type": "keyword"},
"surroundingSuburbs": {"type": "keyword"},
"bedrooms": {"type": "integer"}
}
}
# Saving a search matching on Coburg and surrounding suburbs, but boosting exact Cobug matches
PUT /saved-searches/_doc/1
{
"userId": "1234",
"savedSearchName": "My Coburg and Surrounds Search",
"query": {
"bool": {
"should": [
{
"constant_score": {
"filter": {
"term": {
"suburb": "Coburg VIC 3058"
}
},
"boost": 10
}
}
],
"filter": [
{
"bool": {
"should": [
{
"term": {
"suburb": "Coburg VIC 3058"
}
},
{
"term": {
"surroundingSuburbs": "Coburg VIC 3058"
}
}
]
}
}
]
}
}
}
# Brunswick and surrounds...
PUT /saved-searches/_doc/2
{
"userId": "1234",
"savedSearchName": "My Brunswick and Surrounds Search",
"query": {
"bool": {
"should": [
{
"constant_score": {
"filter": {
"term": {
"suburb": "Brunswick VIC 3056"
}
},
"boost": 10
}
}
],
"filter": [
{
"bool": {
"should": [
{
"term": {
"suburb": "Brunswick VIC 3056"
}
},
{
"term": {
"surroundingSuburbs": "Brunswick VIC 3056"
}
}
]
}
}
]
}
}
}
# Using percolation to find searches that match listings... note the scores returned
GET /saved-searches/_search
{
"query": {
"percolate": {
"field": "query",
"document": {
"suburb": "Coburg VIC 3058",
"bedrooms": 2,
"description": "Large garden, swimming pool",
"surroundingSuburbs": ["Brunswick VIC 3056", "Pascoe Vale 3044", "Preston VIC 3072", "Thornbury VIC 3071", "Coburg North VIC 3058"]
}
}
}
}
GET /saved-searches/_search
{
"query": {
"percolate": {
"field": "query",
"document": {
"suburb": "Brunswick VIC 3056",
"bedrooms": 1,
"description": "Modern kitchen, close to public transport",
"surroundingSuburbs": ["Coburg VIC 3058", "Parkville VIC 3052", "Thornbury VIC 3071", "Brunswick East VIC 3057"]
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment