How to use Phrase Search in Elasticsearch 6 using NodeJS
Introduction
It’s true that you can quickly locate an exact phrase in an index in Elasticsearch. To accomplish the task, you’ll want to use Phrase Search. But if you’re just starting phrase search in Elasticsearch, you may be tempted to conduct a multiple word search with the match
query.
Here’s why match
works for single-word queries but not phrase queries. With match
, when you enter a phrase that contains two or more words, the results will also include data with only one of those words. Let’s explain further. Say you use the match
query to find the phrase “Strawberry Cake.” You just want the results that contain an exact match for “Strawberry Cake.” The match
query will return those results, but also in the mix you could get “Strawberry Ice Cream,” and “Chocolate Cake,” because the former has the word “Strawberry” and the latter has the word “Cake”.
This tutorial shows you step-by-step how to use Phrase Search. If you’re already familiar with the method and would like to skip right to the code, click here to go to Just the Code.
Prerequisites
Before we show you how to perform fuzzy query matches with Elasticsearch in Javascript, it’s important to make sure a few prerequisites are in place. There are only a few of system requirements for this task:
NodeJS needs to be installed
The elasticsearch npm module installed.
A simple npm install elasticsearch
should work in most cases.
Elasticsearch also needs to be installed and running.
* In our example, we have Elasticsearch installed locally using the default port of 9200. If your Elasticsearch installation is running on a different server, you’ll need to modify your javascript syntax accordingly.
An Example Using the Phrase Search Query
Let’s look at an example that uses an index called store
, which represents a small grocery store. This store
index contains a type called products
which lists the store’s products. To keep things simple, our example dataset will only contain a handful of products with just the following fields: id, price, quantity, and department. The code below shows the JSON used to create the dataset:
id | name | price | quantity | department |
---|---|---|---|---|
1 | Multi-Grain Cereal | 4.99 | 4 | Packaged Foods |
2 | 1lb Ground Beef | 3.99 | 29 | Meat and Seafood |
3 | Dozen Apples | 2.49 | 12 | Produce |
4 | Chocolate Bar | 1.29 | 2 | Packaged Foods, Checkout |
5 | 1 Gallon Milk | 3.29 | 16 | Dairy |
6 | 0.5lb Jumbo Shrimp | 5.29 | 12 | Meat and Seafood |
7 | Wheat Bread | 1.29 | 5 | Bakery |
8 | Pepperoni Pizza | 2.99 | 5 | Frozen |
9 | 12 Pack Cola | 5.29 | 6 | Packaged Foods |
10 | Lime Juice | 0.99 | 20 | Produce |
11 | 12 Pack Cherry Cola | 5.59 | 5 | Packaged Foods |
12 | 1 Gallon Soy Milk | 3.39 | 10 | Dairy |
13 | 1 Gallon Vanilla Soy Milk | 3.49 | 9 | Dairy |
14 | 1 Gallon Orange Juice | 3.29 | 4 | Juice |
Here is the json we used to define the mapping if our index:
1 2 3 4 5 6 7 8 9 10 11 12 | { "mappings": { "products": { "properties" : { "name": { "type": "text"}, "price": { "type": "double"}, "quantity": { "type": "integer"}, "department": { "type": "keyword"} } } } } |
Conduct the Phrase Search Query
Your query for a general match to the two-word phrase “Cherry Cola” would look similar to this:
File: app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | var elasticsearch = require("elasticsearch"); var client = new elasticsearch.Client({ hosts: ["http://localhost:9200"] }); /* Match Search */ client.search({ index: 'store', type: 'products', body: { "query": { "match": { "name": "Cherry Cola" } } } }).then(function(resp) { console.log("Successful query!"); console.log(JSON.stringify(resp, null, 4)); }, function(err) { console.trace(err.message);`` }); |
Run app.js in the terminal like this:
1 | $ node app.js |
Response:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | Successful query! { "took": 29, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 2, "max_score": 1.3469357, "hits": [ { "_index": "store", "_type": "products", "_id": "9", "_score": 1.3469357, "_source": { "id": "9", "name": "12 Pack Cola", "price": 5.29, "quantity": 6, "department": [ "Packaged Foods" ] } }, { "_index": "store", "_type": "products", "_id": "11", "_score": 1.219939, "_source": { "id": "11", "name": "12 Pack Cherry Cola", "price": 5.59, "quantity": 5, "department": [ "Packaged Foods" ] } } ] } } |
With the match
query, our results contains two results it: “12 Pack Cola” and “12 Pack Cherry Cola”.
If you’re looking for an exact match to the phrase “Cherry Cola”, use Phrase Search. This way you’ll receive more precision in your search results. Simply change the match
query to match_phrase
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | var elasticsearch = require("elasticsearch"); var client = new elasticsearch.Client({ hosts: ["http://localhost:9200"] }); /* Match Phrase Search */ client.search({ index: 'store', type: 'products', body: { "query": { "match_phrase": { "name": "Cherry Cola" } } } }).then(function(resp) { console.log("Successful query!"); console.log(JSON.stringify(resp, null, 4)); }, function(err) { console.trace(err.message);`` }); |
Response:
`
js
$ node app.js Successful query!
{
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 "took": 1184,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1.219939,
"hits": [
{
"_index": "store",
"_type": "products",
"_id": "11",
"_score": 1.219939,
"_source": {
"id": "11",
"name": "12 Pack Cherry Cola",
"price": 5.59,
"quantity": 5,
"department": [
"Packaged Foods"
]
}
}
]
}
}
`
As you can see, the match_phrase
query limits your query to a result set with exact matches to that phrase.
Conclusion
This Phrase Search in Elasticsearch 6 tutorial showed you how to save time by using the query match_phrase
as opposed to match
. This is because the Phrase Search match_phrase
query zeros in on exactly the search terms you query.
By the way, phrase searching using the match_phrase
query isn’t the only way to search efficiently in Elasticsearch 6. The slop
parameter may be of interest to you as well. Read more on it here. Meanwhile, to learn more about match_phrase
look at the Elasticsearch documentation or reach out to us. We’re here to help.
Just the Code
Here’s a code example showing Phrase Search, the match_phrase
query in action.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | var elasticsearch = require("elasticsearch"); var client = new elasticsearch.Client({ hosts: ["http://localhost:9200"] }); /* Match Phrase Search */ client.search({ index: 'store', type: 'products', body: { "query": { "match_phrase": { "name": "Cherry Cola" } } } }).then(function(resp) { console.log("Successful query!"); console.log(JSON.stringify(resp, null, 4)); }, function(err) { console.trace(err.message);`` }); |
Pilot the ObjectRocket Platform Free!
Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.
Get Started