Correspondências exatas no Atlas Search: guia para desenvolvedores
Avalie esse Artigo
Grande parte deste artigo foi fornecida por uma estagiária do MongoDB, Humanyara Kerim. Graças a você por passar o verão com a nós!
Os mecanismos de pesquisa são ferramentas poderosas nas quais os usuários confiam quando procuram informações. Muitas vezes, eles confiam neles para lidar com o erro ortográfico de palavras por meio de um recurso chamado correspondência difusa. A correspondência difusa identifica texto, string e até mesmo consultas que são muito semelhantes, mas não iguais. Isso é muito útil.
Mas, na maioria das vezes, a pesquisa mais útil é uma correspondência exata. Estou procurando uma palavra,
foobar
e quiser foobar
, não foobarr
e não greenfoobart
.Felizmente, o Atlas Search tem soluções para pesquisas difusas e correspondências exatas. Este tutorial se concentrará nas diferentes maneiras pelas quais os usuários podem obter correspondências exatas, bem como nos prós e contras de cada uma delas. Na verdade, existem algumas maneiras de obter correspondências exatas com o Atlas Search.
Assim como o sistema de metrô de Nova York, há muitas maneiras de chegar ao mesmo destino, e nem todas são boas. Então, vamos falar sobre os vários métodos de fazer pesquisas de correspondência exata e os prós e contras.
Aqui, queremos média "correspondência exata" para média literalmente exatos ou aproximadamente os mesmos. Mais ou menos exato pode média correspondência insensível a maiúsculas e minúsculas, ou correspondência, independentemente de sinais diacríticos serem usados ou não, ou até mesmo correspondência de palavras, independentemente de serem singulares ou plurais.
Se você quiser encontrar uma correspondência exata para uma string de texto, o melhor tipo de campo a ser usado é o tipotoken, pois ele indexa um campo de string como um único termo. O tipo
token
também tem a capacidade de normalizar para minúsculas, para correspondências insensíveis a maiúsculas e minúsculas. O tipotoken
funciona com os operadoresequals
e in
. Aqui está uma configuração de índice para mapear um campocategory
para correspondência e classificação exata do valor:1 { 2 "mappings": { 3 "dynamic": true, 4 "fields":{ 5 "category": [ 6 { 7 "type": "token" 8 } 9 ] 10 } 11 } 12 }
Veja um exemplo que corresponde ao tipo de campo de token
category
usandoequals
:1 [ 2 { 3 $search: { 4 equals: { 5 path: "category", 6 value: "Technology" 7 } 8 } 9 } 10 ]
Para ver essa query em ação, confira no playground de pesquisas
Prós: é o mais exato possível, com uma opção para correspondência insensível a maiúsculas e minúsculas. Como um Bônus adicional, o tipo de campo
token
também pode ser classificado.Contras: isso é exato, ou caso insenstivamente exato – então não há espaço para imprecisão com o tipo de campo
token
.Se você quiser retornar correspondências que contenham uma palavra específica, o Standard Analyzer seria a sua escolha, pois divide os textos com base nos limites das palavras. É crucial primeiro identificar e entender o analisador apropriado de que você precisará com base em seu caso de uso. É aqui que o MongoDB facilita a nossa vida, pois você pode encontrar todos os analisadores integrados que o Atlas Search suporta e seus propósitos em um só lugar, como mostrado abaixo:
Prós: Os usuários também podem criar analisadores personalizados e múltiplos para atender às necessidades específicas de aplicativos. Há exemplos nos fóruns da comunidade de desenvolvedores do MongoDB que demonstram pessoas fazendo isso por acaso.
Aqui está um código para pesquisa sem distinção entre maiúsculas e minúsculas usando um analisador personalizado e com a palavra-chave tokenizer e um filtro de token em minúsculas:
1 { 2 "charFilters": [], 3 "name": "search_keyword_lowercaser", 4 "tokenFilters": [ 5 { 6 "type": "lowercase" 7 } 8 ], 9 "tokenizer": { 10 "type": "keyword" 11 } 12 } 13 ]
Ou um analisador lucene.keyword para queries de correspondência exata de uma palavra e uma consulta de frase para queries de correspondência exata de várias palavras aqui:
1 { 2 $search: { 3 "index": "movies_search_index" 4 "phrase": { 5 "query": "Red Robin", 6 "path": "title" 7 } 8 } 9 }
Contras: quando um analisador está envolvido, as queries operam nos termos da string analisada; a correspondência depende da combinação dos termos analisados e do tipo de query construída.
Como o nome sugere, este operador permite que os usuários pesquisem texto. Veja como fica a sintaxe do operador de texto:
1 { 2 $search: { 3 "index": <index name>, // optional, defaults to "default" 4 "text": { 5 "query": "<search-string>", 6 "path": "<field-to-search>", 7 "fuzzy": <options>, 8 "score": <options>, 9 "synonyms": "<synonyms-mapping-name>" 10 } 11 } 12 }
Se estiver pesquisando um único termo e quiser usar a pesquisa de texto completo para fazer isso, este é o operador ideal para você. Simples, eficaz e sem frescuras. Sua simplicidade significa que é difícil errar, e você pode usá-lo em casos de uso complexos sem se preocupar. Você também pode combinar o operador de texto com outros itens.
1 db.movies.aggregate([ 2 { 3 $search: { 4 "text": { 5 "path": "title", 6 "query": "automobile", 7 "synonyms": "transportSynonyms" 8 } 9 } 10 }, 11 { 12 $limit: 10 13 }, 14 { 15 $project: { 16 "_id": 0, 17 "title": 1, 18 "score": { $meta: "searchScore" } 19 } 20 } 21 ])
1 db.movies.aggregate([ 2 { 3 $search: { 4 "text": { 5 "query": "Helsinki", 6 "path": "plot" 7 } 8 } 9 }, 10 { 11 $project: { 12 plot: 1, 13 title: 1, 14 score: { $meta: "searchScore" } 15 } 16 } 17 ])
Prós: Simples e fácil de usar.
Contras: as correspondências exigem que todos ou qualquer um dos termos corresponda. Não há meio termo de mais de um deve corresponder, mas não necessariamente todos os termos.
O operador
phrase
pode obter queries de correspondência exata em várias palavras (termos) em um campo. Mas por que usar um operador de frase em vez de text
? É porque o operador de frase procura uma sequência ordenada de termos com a ajuda de um analisador definido na configuração do índice. Dê uma olhada neste exemplo, em que queremos pesquisar as frases "the man " e "the moon " em uma coleção de títulos de filmes:1 db.movies.aggregate([ 2 { 3 "$search": { 4 "phrase": { 5 "path": "title", 6 "query": ["the man", "the moon"] 7 } 8 } 9 }, 10 { $limit: 10 }, 11 { 12 $project: { 13 "_id": 0, 14 "title": 1, 15 score: { $meta: "searchScore" } 16 } 17 } 18 ])
Como você pode ver, a query retorna todos os resultados que contêm termos de sequência ordenada "the man " e "the moon. "
1 { "title" : "The Man in the Moon", "score" : 4.500046730041504 } 2 { "title" : "Shoot the Moon", "score" : 3.278003215789795 } 3 { "title" : "Kick the Moon", "score" : 3.278003215789795 } 4 { "title" : "The Man", "score" : 2.8860299587249756 } 5 { "title" : "The Moon and Sixpence", "score" : 2.8754563331604004 } 6 { "title" : "The Moon Is Blue", "score" : 2.8754563331604004 } 7 { "title" : "Racing with the Moon", "score" : 2.8754563331604004 } 8 { "title" : "Mountains of the Moon", "score" : 2.8754563331604004 } 9 { "title" : "Man on the Moon", "score" : 2.8754563331604004 } 10 { "title" : "Castaway on the Moon", "score" : 2.8754563331604004 }
Prós: Há algumas opções que você pode usar com a frase que dão aos usuários a flexibilidade de personalizar as frases exatas que desejam corresponder.
Contras: Todos os termos na query devem corresponder, nessa ordem especificada.
Embora esse recurso não seja sobre correspondência, vale a pena destacar. (Viu o que eu fez lá?!)
Eu adoro esse recurso. É muito útil. O destaque permite que os usuários vejam visualmente as correspondências exatas. Esta opção também permite que os usuários retornem visualmente os termos de pesquisa em seu contexto original. Na UI do seu aplicativo, o recurso de destaque se parece com isto:
Se você estiver interessado em aprender a criar um aplicativo como esse, aqui está um tutorialpasso a passo que mostra visualmente os destaques da Atlas Search com JavaScript e HTML.
Prós: Esteticamente, esse recurso melhora a experiência de pesquisa do usuário porque os usuários podem ver facilmente o que procuram em um determinado texto.
Contras: Pode ser caro se as passagens forem longas porque será necessária muito mais RAM para manter os dados.
Por fim, há muitas maneiras de obter correspondências exatas('ish) com Atlas Search o . Sua melhor abordagem é ler alguns dos tutoriais na documentação e dar uma Atlas Search olhada na seção aqui no DevCenter e então consertar ela.