Docs Menu

Docs HomeLaunch & Manage MongoDBMongoDB Atlas

span

On this page

  • Definition
  • Syntax
  • Term Operator
  • Syntax
  • Fields
  • Positional Operators
  • contains
  • first
  • near
  • or
  • subtract

Note

The span operator is deprecated. Instead, use the phrase operator.

span

The span operator finds text search matches within regions of a text field. You can use it to find strings which are near each other to specified degrees of precision. The span operator is more computationally intensive than other operators, because queries must keep track of positional information.

span is a term-level operator, which means that the query field is not analyzed. Term-level operators work well with the Keyword Analyzer because the query field is treated as a single term, with special characters included.

span queries aren't ranked by score.

span has the following syntax:

{
$search: {
"index": <index name>, // optional, defaults to "default"
"span": {
"term" | <positional-operator>": {
<operator-specification>
}
}
}
}

Note

span search queries can't use the compound operator.

You can use the term operator to specify the terms to search. The term operator is required and when you use it with span positional operators, it must be the innermost child of the positional operators.

The term operator has the following syntax:

"term": {
"path": "<path-to-field>",
"query": "<terms-to-search>"
}

The term operator takes the following fields:

Option
Type
Required?
Description
path
string
yes
Indexed field to search.
query
string
yes
Term or phrase to search.

You can use the positional operators to specify the position of the terms that you want to search with the term operator. The positional operators are of type document. You must specify at least one positional operator in your span operator query. The positional operators can take other span positional operators, recursively.

Note

About the Examples

The examples on this page use the sample_mflix.movies collection. If you load the sample data and create a dynamic index named default on the movies collection , you can run the following $search sample queries against the collection. The sample queries use the $limit stage to limit the results to 5 documents and the $project stage to exclude all fields except the title field in the results.

span takes the following optional positional operators.

The contains positional operator matches terms that are contained within other terms. You can use positional operators recursively or just the term operator within contains to specify the search terms.

The contains positional operator has the following syntax:

{
"$search": {
"span": {
"contains": {
"spanToReturn": "inner"|"outer",
"little": { <positional-or-term-operator-specification> },
"big": { <positional-or-term-operator-specification> }
}
}
}
}

The contains positional operator takes the following fields:

Fields
Type
Required?
Description
big
document
yes

One or more positional operators specified recursively or just the term operator. The following table shows the type of query that span executes for big based on the value of spanToReturn.

outer
span matches terms from big that contain at least one term from little.
inner
span matches terms from little that are within terms from big.
little
document
yes

One or more positional operators specified recursively or just the term operator. The following table shows the type of query that span executes for little based on the value of spanToReturn.

inner
span matches terms from little that are within terms from big.
outer
span matches terms from big that contain at least one term from little.
score
document
no
Score to apply to the results of this search.
spanToReturn
string
yes

Type of query to execute and matching results to return. Value can be one of the following:

  • inner - to execute a within query that matches terms from little that are inside of terms from big

  • outer - to execute a contains query that matches terms from big that contain at least one term from little

The following example query uses span.contains to find documents in which the term train appears with the terms great and robbery, where great and robbery can be up to 5 positions apart in the title field.

1db.movies.aggregate([
2 {
3 "$search": {
4 "span": {
5 "contains": {
6 "spanToReturn": "outer",
7 "little": {
8 "term": {
9 "path": "title",
10 "query": "train"
11 }
12 },
13 "big": {
14 "near": {
15 "clauses": [
16 {
17 "term": {
18 "path": "title",
19 "query": "great"
20 }
21 },
22 {
23 "term": {
24 "path": "title",
25 "query": "robbery"
26 }
27 }
28 ],
29 "slop": 5
30 }
31 }
32 }
33 }
34 }
35 },
36 {
37 "$limit": 5
38 },
39 {
40 "$project": {
41 "_id": 0,
42 "title": 1
43 }
44 }
45])
[
{ title: 'The Great Train Robbery' },
{ title: 'The Great Train Robbery' },
{ title: "The Great St. Trinian's Train Robbery" }
]

Atlas Search returns documents that contain the term train (specified using little) inside the terms great and robbery (specified using big). If you set spanToReturn on line 6 to inner, Atlas Search returns the same documents because the term train (specified using little) appears within the terms great and robbery (specified using big).

The first positional operator identifies the position of the search term by using a specified number. You can specify the search terms using positional operators recursively, or just the term operator. span matches documents where the position of the search term is less than or equal to the specified number.

The first positional operator has the following syntax:

{
"$search": {
"span": {
"first": {
"endPositionLte": <term-position>,
"operator": { <span-positional-or-term-operator-specification> },
"score": { <score-options> }
}
}
}
}

The first positional operator takes the following fields:

Option
Type
Required?
Description
endPositionLte
int
no
Number that specifies the position of the search term. If you specify a search for multiple terms, the last term should be less than or equal to this value. If omitted, defaults to 3.
operator
document
yes
Document that contains the positional operators or term operator options.
score
document
no
Score to apply to the results of this search.

The following example queries use span.first to find documents in which the specified string appears in the title field. The endPositionLte parameter has a value of 2, which means that the search term specified using the term operator must be the first or second word in the field.

The near positional operator matches two or more clauses that contain the search term near each other. You can specify the search terms using a list of positional operators recursively or just the term operator.

The near positional operator has the following syntax:

{
"$search": {
"span": {
"near": {
"clauses": [
{ <span-positional-or-term-operator-specification> },
...
],
"slop": <distance-number>,
"inOrder": true|false
}
}
}
}

The near positional operator takes the following fields:

Field
Type
Required?
Description
clauses
array of documents
yes
Span clauses that must be near one another. Clauses can't be empty. Each document contains span positional or just the term operator options.
inOrder
boolean
no

Flag that specifies whether the search for terms in the clauses must be in the order specified and must not be overlapping.

Value can be one of the following:

  • true - to search for terms in the clauses in the specified order specified, without overlapping

  • false - to search for terms in the clauses in any order

If omitted, defaults to false.

score
document
no
Score to apply to the results of this search.
slop
integer
no
Allowable distance between terms in the clauses. Lower values allow less positional distance between the terms and greater values allow more distance between the words to satisfy the query. The default is 0, which means that words in the different clauses must be adjacent to be considered a match.

The following example query uses span.near to search for documents in which the strings prince and pauper are found near each other. The inOrder parameter is set to false, so the search terms can be in any order. The slop parameter is set to 4, so the search terms can be separated by up to only 4 words.

1db.movies.aggregate([
2 {
3 "$search" : {
4 "span": {
5 "near": {
6 "clauses": [
7 { "term": { "path": "title", "query": "prince" } },
8 { "term": { "path": "title", "query": "pauper" } }
9 ],
10 "slop": 4,
11 "inOrder": false
12 }
13 }
14 }
15 },
16 {
17 "$limit": 5
18 },
19 {
20 "$project": {
21 "_id": 0,
22 "title": 1
23 }
24 }
25])
[ { title: 'The Prince and the Pauper' } ]

Atlas Search returns a document that contain search words prince and pauper, separated by less than four words, in the title field.

The or positional operator matches any of two or more clauses. You can specify the search terms using a list of positional operators recursively or just the term operator.

The or positional operator has the following syntax:

{
"$search": {
"span": {
"or": {
"clauses": [
{ <span-positional-or-term-operator-specification> },
...
],
"score": { <scoring-options> }
}
}
}
}

The or positional operator takes the following fields:

Option
Type
Required?
Description
clauses
array of documents
yes
Span clauses that specify the search terms. One of the clauses must match, and clauses can't be empty. Each document must contain span positional operators specified recursively or just the term operator options.
score
document
no
Score to apply to the results of this search.

The following example query uses span.or clauses to specify two term operator queries that search for documents in which the title field has either city or country.

1db.movies.aggregate([
2 {
3 "$search" : {
4 "span": {
5 "or": {
6 "clauses": [
7 { "term": { "path": "title", "query": "city" } },
8 { "term": { "path": "title", "query": "country" } }
9 ],
10 }
11 }
12 }
13 },
14 {
15 "$limit": 5
16 },
17 {
18 "$project": {
19 "_id": 0,
20 "title": 1
21 }
22 }
23])
[
{ title: 'Country' },
{ title: 'City Lights' },
{ title: 'King & Country' },
{ title: 'Fat City' },
{ title: 'Atlantic City' }
]

Atlas Search returns the documents that contain the search words city or country in the title field, but not both in the same title.

The subtract positional operator removes matches that overlap with another match. You can specify the search terms using a list of positional operators recursively or just the term operator. The subtract clause can be used to exclude certain strings from your search results.

The subtract positional operator has the following syntax:

{
"$search": {
"span": {
"subtract": {
"include": { <span-positional-or-term-operator-specification> },
"exclude": { <span-positional-or-term-operator-specification> }
}
}
}
}

The subtract positional operator takes the following fields:

Option
Type
Required?
Description
exclude
document
yes
Document that specifies the term or phrase matches to remove that overlap with the term or phrase matches specified in the include field. You can specify the term or phrase using any span positional operators and the term operator.
include
document
yes
Document that specifies the term matches to include using any positional operators or just the term operator.
score
document
no
Score to apply to the results of this search.

The following example query uses span.subtract to search for documents in which the title field contains the words father and son, in any order, within 3 words of each other. It excludes any document in which the word like occurs between father and son.

1db.movies.aggregate([
2 {
3 "$search" : {
4 "span": {
5 "subtract": {
6 "include": {
7 "near": {
8 "clauses": [
9 { "term": { "path": "title", "query": "father" } },
10 { "term": { "path": "title", "query": "son" } }
11 ],
12 "inOrder": false,
13 "slop": 3
14 }
15 },
16 "exclude": { "term": { "path": "title", "query": "like" } }
17 }
18 }
19 }
20 },
21 {
22 "$limit": 5
23 },
24 {
25 "$project": {
26 "_id": 0,
27 "title": 1
28 }
29 }
30])
[
{ title: 'Father, Son & Holy Cow' },
{ title: 'My Father and My Son' },
{ title: 'Jimmy Rosenberg: The Father, the Son & the Talent' }
]

Atlas Search doesn't return the document with the title Like Father Like Son because although the title field includes the words father and son, it also has like between them, which is in the exclude criteria of the query.

←  regextext →