Welcome back to the second part of our blog series on MongoDB Atlas Full-Text Search. In the first part, "From Indexing to Querying: How MongoDB's Full-Text Search Stacks Up Against Elasticsearch," we explored the fundamentals of MongoDB's full-text search and compared it to Elasticsearch. If you haven't read it yet, we highly recommend starting there to get a comprehensive understanding of MongoDB's full-text search capabilities. In this blog post, we will dive deeper into MongoDB Atlas Full-Text Search and explore advanced querying techniques that will enable you to take full advantage of its powerful features.
Understanding Compound Queries.
Compound queries are very important and powerful when it comes to real-world use cases.
A compound operator in MongoDB combines multiple operators to form a single query. Each part of the compound query is referred to as a clause, and each clause contains one or more sub-queries.
A compound query has the following syntax:
{
$search: {
"index": <index name>, // optional, defaults to "default"
"compound": {
<must | mustNot | should | filter>: [ { <clauses> } ],
"score": <options>
}
}
}
Explanation:
Each must, mustNot, should, and filter clause contains an array of subclauses. Use array syntax even if the array contains only one subclause.
We required the following terms to construct the query, which we also explained above -
Document for explaining all the queries -
{
"_id" : 1,
"type" : "apple",
"description" : "Apples come in several varieties, including Fuji, Granny Smith, and Honeycrisp.",
"category" : "nonorganic",
"in_stock" : false
},
{
"_id" : 2,
"type" : "banana",
"description" : "Bananas are usually sold in bunches of five or six.",
"category" : "nonorganic",
"in_stock" : true
},
{
"_id" : 3,
"type" : "pear",
"description" : "Bosc and Bartlett are the most common varieties of pears.",
"category" : "organic",
"in_stock" : true
}
Operators -
- must Clauses that must match for a document to be included in the results. The returned score is the sum of the scores of all the subqueries in the clause.
Maps to the AND boolean operator.
Example:
db.col.aggregate([
{
$search: {
"compound": {
"must": [{
"text": {
"query": "varieties",
"path": "description"
}
}]
}
}
}
])
Explanation :
In the above query we are searching for the term
Varieties
in the fielddescription
which is calledpath
in the query, and this query will return only those document which contains this -Varieties
term in the field -description
.
- mustNot Clauses that must not match for a document to be included in the results. mustNot clauses don't contribute to a returned document's score.
Maps to the AND NOT boolean operator.
Example:
db.col.aggregate([
{
$search: {
"compound": {
"mustNot": [{
"text": {
"query": "apples",
"path": "description"
}
}]
}
}
}
])
Explanation :
In the above query we are searching for the data which do not contains apples in the field description, so this query will return only those documents which do not have apples in the field description.
- should Clauses that you prefer to match in documents that are included in the results. Documents that contain a match for a should clause have higher scores than documents that don't contain a should clause. The returned score is the sum of the scores of all the subqueries in the clause.
If you use more than one should clause, you can use the minimumShouldMatch option to specify a minimum number of should clauses that must match to include a document in the results. If omitted, the minimumShouldMatch option defaults to 0.
Maps to the OR boolean operator.
Example:
db.col.aggregate([
{
$search: {
"compound": {
"Should": [{
"text": {
"query": "apples",
"path": "description"
}
}]
}
}
}
])
Explanation :
In the above query we are searching for the data which contains apples in the field description, so this query will return those documents which have apples in the field description.
for a better understanding of this Should operator which is the OR operator also, here is a second example -
db.col.aggregate([
{
$search: {
"compound": {
"Should": [{
"text": {
"query": "apples",
"path": "description"
},
"text": {
"query": "Banana",
"path": "description"
}
}],
"minimumShouldMatch": 1
}
}
}
])
Explanation :
In the above query we are searching for the data which contains
apples
ORBanana
in the fielddescription
, so thisquery
will return those documents which have either apples or Banana in the fielddescription
, also if you noticed we added"minimumShouldMatch": 1
in this query,minimumShouldMatch
means specify a minimum number of should clauses that must match to include a document in the results(the given term has to occur specific times whatever we pass as a parameter,default
it is 0)
- filter Clauses must all match for a document to be included in the results. filter clauses do not contribute to a returned document's score.
in other words, it is a replacement of $in operator in full-text search.
filter behaves the same as must, except that the filter clause is not considered in a returned document's score, and therefore does not affect the order of the returned documents.
Example:
$search: {
"compound": {
"filter": [{
"text": {
"query": ["CLIENT", "PROFESSIONAL"],
"path": "role"
}
}]
}
}
Now, as we understand all the important operators of full-text search, here a an example of a query which combines all these operators to get the result.
Query -
db.col.aggregate([
{
$search: {
"compound": {
"must": [{
"text": {
"query": "varieties",
"path": "description"
}
}],
"mustNot": [{
"text": {
"query": "apples",
"path": "description"
}
}],
"should": [
{
"text": {
"query": "Fuji",
"path": "description"
}
},
{
"text": {
"query": "Golden Delicious",
"path": "description"
}
}],
"minimumShouldMatch": 2
}
}
}
])
Explanation:
The following example uses a combination of
must
,mustNot
,Should
clauses to construct aquery
. Themust
clause uses the text operator tosearch
for the termvarieties
in the description field. For a document to match, it must fulfil themust
clause. ThemustNot
clause performs asearch
operation for the termapples
in thedescription
field. For a document to match, it must not fulfil themustNot
clause. TheShould
clause uses the text operator tosearch
for the termFuji
orGolden Delicious
in the description field. For a document to match either of them at least 2 times i.e.minimumShouldMatch
we used, it will return any terms or both terms given if it occurs more than 1.
I hope you find this blog post informative and helpful as you dive deeper into MongoDB Atlas Full-Text Search. Happy querying!
Top comments (0)