Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
MongoDB Branding Shape
Click here >
Menu Docs

Use MongoDB Search em vez de queries Regex

Se suas queries dependerem da correspondência de regex, você poderá melhorar o desempenho e a eficiência da sua query criando um índice do MongoDB Search e executando uma fase do pipeline de agregação $search. $regex é ineficiente porque nem sempre pode fazer uso de índices, enquanto os índices do MongoDB Search melhoram significativamente o desempenho de suas queries e oferecem mais opções para personalizar parâmetros de query.

Esta página descreve algumas configurações comuns de índice e query do MongoDB Search para casos de uso$regex.

Os exemplos utilizam um namespace do sample_mflix.movies. Para executar as queries de amostra, adicione esta coleção ao seu cluster ou use os snapshots pré-configurados no MongoDB Search Playground. As queries de exemplo demonstram como utilizar o $search ao invés do $regex para os seguintes casos de uso:

Se o seu aplicativo query frequentemente valores de string que começam com um conjunto de caracteres ou prefixo, ele poderá usar a opção $regex ^, que pesquisa desde o início do valor da string, e i, que a torna maiúsculas e minúsculas- insensível.

Em vez disso, recomendamos queries do MongoDB Search que usem o estágio do pipeline de agregação $search. As queries a seguir procuram títulos de filmes que começam com o prefixo back.

➤ Tente fazer isso no playground do MongoDB Search.

$regex Consultas
$search Query
db.movies.find( { title: { $regex: /^back/i } }, { title: 1, _id: 0 } ) // Query 1
db.movies.find( { title: { $regex: "^back", $options: "i" } }, { title: 1, _id: 0 } ) // Query 2
[
{ title: 'Back to the Future' },
{ title: 'Back to School' },
{ title: 'Back to the Future Part II' },
{ title: 'Back to the USSR - takaisin Ryssiin' },
{ title: 'Back to the Future Part III' },
{ title: 'Backdraft' },
{ title: 'Backbeat' },
{ title: 'Backstage' },
{ title: 'Backdoor' },
{ title: 'Backstage' },
{ title: 'Back Soon' },
{ title: 'Backlight' },
{ title: 'Back to Stay' },
{ title: 'Back Issues: The Hustler Magazine Story' }
]
db.movies.aggregate([
{
"$search": {
"index": "default",
"text": {
"query": "back",
"path": "title",
"matchCriteria": "all"
}
}
},
{
"$project": {
"_id": 0,
"title": 1,
"score": { $meta: "searchScore" }
}
}
])
[
{ title: 'Backdraft', score: 3.8287878036499023 },
{ title: 'Backbeat', score: 3.8287878036499023 },
{ title: 'Backstage', score: 3.8287878036499023 },
{ title: 'Backdoor', score: 3.8287878036499023 },
{ title: 'Backstage', score: 3.8287878036499023 },
{ title: 'The Backwoods', score: 3.8287878036499023 },
{ title: 'The Backwoods', score: 3.8287878036499023 },
{ title: 'The Way Back', score: 3.8287878036499023 },
{ title: '3 Backyards', score: 3.8287878036499023 },
{ title: 'Backlight', score: 3.8287878036499023 },
{ title: 'The Way Way Back', score: 3.8287878036499023 },
{ title: 'Back to the Future', score: 3.455096483230591 },
{ title: 'Back to School', score: 3.455096483230591 },
{ title: 'The Cat Came Back', score: 3.455096483230591 },
{ title: "Jack's Back", score: 3.455096483230591 },
{ title: 'The Dark Backward', score: 3.455096483230591 },
{ title: 'T-Rex: Back to the Cretaceous', score: 3.455096483230591 },
{ title: 'The Dark Backward', score: 3.455096483230591 },
{ title: 'No Turning Back', score: 3.455096483230591 },
{ title: "The Devil's Backbone", score: 3.455096483230591 }
]
Type "it" for more

Para executar esta $search query, crie um índice de MongoDB Search semelhante ao seguinte:

{
"mappings": {
"dynamic": false,
"fields": {
"title": [
{
"type": "string",
"analyzer": "autocomplete-search",
"searchAnalyzer": "lucene.standard"
}
]
}
},
"analyzers": [
{
"name": "autocomplete-search",
"tokenizer": {
"type": "standard"
},
"tokenFilters": [
{
"type": "lowercase"
},
{
"type": "edgeGram",
"minGram": 4,
"maxGram": 10
}
]
}
]
}

Essa definição de índice indexa o campo title na coleção movies como o tipo string que usa o analisador personalizado autocomplete-search para campos indexados e o analisador lucene.standard para queries. O analisador personalizado nomeou autocomplete-search como analyzer para campos indexados e o lucene.standard como searchAnalyzer para queries. O analisador personalizado chamado

  • lowercase filtro de token para transformar todos os caracteres em minúsculas para dar suporte a queries que não diferenciam maiúsculas de minúsculas

  • edgeGram filtro de token para criar tokens de 4 a 10 caracteres de comprimento

Observação

Esse analisador personalizado suporta apenas palavras com até dez caracteres. Se você espera palavras e queries com mais de dez caracteres, aumente o valor maxGram. Não recomendamos definir um valor maxGram superior a 15 porque valores mais altos aumentam o tamanho do índice e podem impacto o desempenho e a disponibilidade.

Se o seu aplicativo query com frequência strings que estão presentes em qualquer lugar no campo, você pode executar queries$regex, que verificam cada documento e retornam todas as correspondências em nenhuma ordem específica.

Em vez disso, recomendamos queries do MongoDB Search que usem o estágio do pipeline de agregação $search. As queries a seguir procuram títulos de filmes que contenham o termo park em qualquer lugar do campo title.

➤ Tente fazer isso no playground do MongoDB Search.

$regex Query
$search Query
db.movies.find({ title: { $regex: "park", $options: "i" } }, { title: 1, _id: 0 })
[
{ title: 'Barefoot in the Park' },
{ title: 'The Panic in Needle Park' },
{ title: 'Gorky Park' },
{ title: 'The Park Is Mine' },
{ title: 'Jurassic Park' },
{ title: 'Mrs. Parker and the Vicious Circle' },
{ title: 'The Lost World: Jurassic Park' },
{ title: 'Dog Park' },
{ title: 'South Park: Bigger Longer & Uncut' },
{ title: 'Jurassic Park III' },
{ title: 'Mansfield Park' },
{ title: 'Jurassic Park III' },
{ title: 'Gosford Park' },
{ title: 'The Rosa Parks Story' },
{ title: 'The Delicate Art of Parking' },
{ title: 'Wicker Park' },
{ title: 'Chestnut: Hero of Central Park' },
{ title: 'Trailer Park Boys: The Movie' },
{ title: 'Ellie Parker' },
{ title: 'Paranoid Park' }
]
db.movies.aggregate([
{
"$search": {
"index": "default",
"wildcard": {
"query": "park*",
"path": "title",
"allowAnalyzedField": true
}
}
},
{
"$project": {
"_id": 0,
"title": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{ title: 'Barefoot in the Park', score: 1 },
{ title: 'The Panic in Needle Park', score: 1 },
{ title: 'Gorky Park', score: 1 },
{ title: 'The Park Is Mine', score: 1 },
{ title: 'Jurassic Park', score: 1 },
{ title: 'Mrs. Parker and the Vicious Circle', score: 1 },
{ title: 'The Lost World: Jurassic Park', score: 1 },
{ title: 'Dog Park', score: 1 },
{ title: 'South Park: Bigger Longer & Uncut', score: 1 },
{ title: 'Jurassic Park III', score: 1 },
{ title: 'Mansfield Park', score: 1 },
{ title: 'Jurassic Park III', score: 1 },
{ title: 'Gosford Park', score: 1 },
{ title: 'The Rosa Parks Story', score: 1 },
{ title: 'Wicker Park', score: 1 },
{ title: 'The Delicate Art of Parking', score: 1 },
{ title: 'Chestnut: Hero of Central Park', score: 1 },
{ title: 'Trailer Park Boys: The Movie', score: 1 },
{ title: 'Ellie Parker', score: 1 },
{ title: 'Paranoid Park', score: 1 }
]
Type "it" for more

Para executar esta $search query, crie um índice de Pesquisa MongoDB com a seguinte definição:

{
"mappings": {
"dynamic": false,
"fields": {
"title": {
"type": "string",
"analyzer": "contains",
"searchAnalyzer": "lucene.standard"
}
}
},
"analyzers": [
{
"name": "contains",
"tokenizer": {
"type": "standard"
},
"tokenFilters": [
{
"type": "lowercase"
},
{
"type": "reverse"
},
{
"type": "edgeGram",
"minGram": 4,
"maxGram": 15
},
{
"type": "reverse"
}
]
}
]
}

Essa definição de índice indexa o campo title na coleção movies como o tipo string usando um analisador personalizado chamado contains que aplica o seguinte:

  • standard tokenizador para divisão as palavras por espaço em branco ou pontuação.

  • lowercase filtro de token para transformar as letras em minúsculas para dar suporte a queries sem distinção entre maiúsculas e minúsculas.

  • reverse filtro de token (duas vezes) para inverter as palavras para suporte queries não ancoradas eficientes.

  • edgeGram filtro de token para criar tokens de comprimento entre quatro e 15 caracteres.

Observação

Esse analisador personalizado suporta apenas palavras com até 15 caracteres. Se você tiver palavras com mais de 15 caracteres, aumente o valor de maxGram. Não é recomendável definir um valor maxGram superior a 15 porque valores mais altos aumentam o tamanho do índice e podem impacto o desempenho e a disponibilidade.

Se o seu aplicativo query com frequência os valores de campos de string que terminam com um conjunto de caracteres ou sufixo, executar queries regex com a opção $regex $, que procura o final do valor da string, e a opção i, que torna insensível a maiúsculas e minúsculas.

Em vez disso, recomendamos queries do MongoDB Search que usem o estágio do pipeline de agregação $search. As queries a seguir pesquisam títulos de filmes que terminem com o termo ring.

➤ Tente fazer isso no playground do MongoDB Search.

$regex Consultas
$search Query
db.movies.find( { title: { $regex: "ring$" } }, { title: 1, _id: 0 } ) // Case-sensitive Query 1
db.movies.find( { title: { $regex: /ring$/ } }, { title: 1, _id: 0 } ) // Case-sensitive Query 2
db.movies.find( { title: { $regex: /ring$/i } }, { title: 1, _id: 0 } ) // Case-insensitive Query 1
db.movies.find( { title: { $regex: "ring$", $options: "i" } }, { title: 1, _id: 0 } ) // Case-insensitive Query 2
[
{ title: 'It Happens Every Spring' },
{ title: 'Larks on a String' },
{ title: 'Release the Prisoners to Spring' },
{ title: 'Manon of the Spring' },
{ title: 'Floundering' },
{ title: 'Autumn Spring' },
{ title: 'The Gathering' },
{ title: 'Blue Spring' },
{ title: 'Blue Spring' },
{ title: 'Girl with a Pearl Earring' },
{ title: 'Spring, Summer, Fall, Winter... and Spring' },
{ title: 'Breaking and Entering' },
{ title: 'Hunting and Gathering' },
{ title: 'Blood Tea and Red String' },
{ title: 'Warm Spring' },
{ title: 'The Conjuring' },
{ title: 'Thanks for Sharing' },
{ title: 'Leaving on the 15th Spring' }
]
db.movies.aggregate([
{
"$search": {
"index": "default",
"autocomplete": {
"query": "ring",
"path": "title",
}
}
},
{
"$project": {
"_id": 0,
"title": 1,
"score": { $meta: "searchScore" }
}
}
])
[
{ title: 'It Happens Every Spring', score: 4.683838844299316 },
{ title: 'Larks on a String', score: 4.683838844299316 },
{
title: 'Release the Prisoners to Spring',
score: 4.683838844299316
},
{ title: 'Manon of the Spring', score: 4.683838844299316 },
{ title: 'Floundering', score: 4.683838844299316 },
{
title: 'The Lord of the Rings: The Fellowship of the Ring',
score: 4.683838844299316
},
{ title: 'Autumn Spring', score: 4.683838844299316 },
{ title: 'The Gathering', score: 4.683838844299316 },
{ title: 'The Ring', score: 4.683838844299316 },
{ title: 'Tom and Jerry: The Magic Ring', score: 4.683838844299316 },
{ title: 'Blue Spring', score: 4.683838844299316 },
{ title: 'Blue Spring', score: 4.683838844299316 },
{ title: 'Girl with a Pearl Earring', score: 4.683838844299316 },
{
title: 'Spring, Summer, Fall, Winter... and Spring',
score: 4.683838844299316
},
{ title: 'Curse of the Ring', score: 4.683838844299316 },
{ title: 'Breaking and Entering', score: 4.683838844299316 },
{ title: 'Closing the Ring', score: 4.683838844299316 },
{ title: 'Hunting and Gathering', score: 4.683838844299316 },
{ title: 'Blood Tea and Red String', score: 4.683838844299316 },
{ title: 'Warm Spring', score: 4.683838844299316 }
]
Type "it" for more

Para executar esta $search query, crie um índice de MongoDB Search semelhante ao seguinte:

{
"mappings": {
"dynamic": false,
"fields": {
"title": [
{
"type": "autocomplete",
"minGrams": 4,
"maxGrams": 10,
"analyzer": "lucene.keyword",
"tokenization": "rightEdgeGram"
}
]
}
}
}

Esta definição de índice indexa o campo title utilizando o:

  • O tipo autocomplete com a estratégia de tokenização rightEdgeGram para divisão o texto em substrings ou "gramas" entre 4 (mínimo) e 10 (máximo) caracteres de comprimento, que suporta pesquisas parciais a partir do final de a string.

  • O analisador lucene.keyword deve garantir as correspondências apenas no final do texto e não no final das palavras intermediárias. Para encontrar correspondências de sufixo em palavras intermediárias, use lucene.standard.

  • Para saber mais sobre queries de pesquisa MongoDB, consulte Queries e índices.

  • Para saber mais sobre queries regex no MongoDB, consulte $regex.

  • A Universidade de MongoDB oferece um curso gratuito sobre como otimizar o desempenho do MongoDB. Para saber mais, consulte Monitoramento e insights.