Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Saiba por que o MongoDB foi selecionado como um líder no 2024 Gartner_Magic Quadrupnt()
Desenvolvedor do MongoDB
Centro de desenvolvedores do MongoDB
chevron-right
Produtos
chevron-right
Atlas
chevron-right

Descubra seu Airbnb ideal: implementando um Spring Boot e Atlas Search com o driver Kotlin Sync

Ricardo Mello8 min read • Published Aug 06, 2024 • Updated Oct 02, 2024
SpringKotlinAtlas
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Uma das minhas atividades favoritas é viajar e explorar o mundo. Você conhece essa impressão de descobrir um novo lugar e pensar: "Como não estava aqui antes?" É com essa impressão que sempre me motivo a procurar novos lugares para descobrir. Muitas vezes, ao procurar um lugar para ficar, não temos certeza do que procuramos ou quais experiências queremos ter. Por exemplo, podemos querer alugar um quarto em uma cidade com vista para um mapa. Encontrar algo assim pode parecer difícil, não é mesmo? No entanto, há uma maneira de pesquisar informações com precisão usando o Atlas Search.
Neste tutorial, aprenderemos a criar um aplicação em Kotlin que utiliza a pesquisa de texto completo em um banco de dados de dados contendo milhares de anúncios do Airbnb. Veremos como podemos encontrar a hospedagem perfeita que atenda às nossas necessidades específicas.

Versão do vídeo

Aqui está uma versão em vídeo deste artigo, se você preferir assistir.

Demonstração

Para atingir nosso objetivo, criaremos um aplicação Kotlin Spring Boot que se comunica com o MongoDB Atlas usando o driver Kotlin Sync.
O aplicativo usará um banco de dados pré-importado no Atlas chamado sample_airbnb, utilizando a collectionlistingsAndReviews, que contém informações sobre vários Airbnbs.
Para identificar os melhores anúncios do Airbnb, criaremos um endpoint que retornará informações sobre esses anúncios. Esse endpoint usará o summary campo da collection para executar uma pesquisa de texto completo com o parâmetro fuzzy no operador de texto. Além disso, filtraremos os documentos com base em um número mínimo de revisões, utilizando as funcionalidades de pesquisa fornecidas pelo Atlas Search.
Gif Um carteiro demonstrando uma solicitação do Atlas Search
figura: um carteiro demonstrando uma solicitação do Atlas Search.

Pré-requisitos

  • Conta do MongoDB Atlas
    • Comece a usar o MongoDB Atlas gratuitamente! Se você ainda não tiver uma conta, o MongoDB oferece um cluster Atlas gratuito para sempre.
  • IDE de sua escolha

O que é o Atlas Search?

Atlas Search é um recurso no MongoDB Atlas que fornece recursos poderosos e flexíveis do Atlas Search para seus dados. Ele se integra ao Apache Lucene, permitindo análise avançada de texto, pontuação personalizada e realce de resultados. Isso permite que você crie a funcionalidade sofisticada do Atlas Search diretamente nos seus aplicativos MongoDB .
Para utilizar o Atlas Search de forma eficaz, vamos nos concentrar em três operadores principais: text, rangee compound. Embora haja vários operadores disponíveis, nossa análise se concentrará neles para ilustrar suas aplicações práticas.
  • Texto: esse operador será usado para realizar pesquisas de texto em nosso endpoint, permitindo a correspondência aproximada e as variações de manuseio nos termos de pesquisa.
  • Faixa : exploraremos o range operador especificamente com a condição gte (maiorou igual a) para o number_of_reviews campo . Isso nos permitirá fazer query e filtrar com base nas contagens de avaliações de forma eficaz.
  • Composto: O compound operador será utilizado para combinar as text fuzzy range queries e em uma pesquisa mais complexa e refinada. Isso demonstrará como mesclar vários critérios para uma funcionalidade de pesquisa mais sofisticada.
Embora este artigo não se aprofunde em todos os operadores disponíveis, os interessados em uma análise mais abrangente podem consultar a documentação do MongoDB Atlas Atlas Search para obter mais detalhes.

Carregar conjunto de dados de amostra

Antes de iniciar, você precisará importar o conjunto de dados de exemplo, que inclui vários bancos de dados e coleções, como a lista do Airbnb. Após configurar seu cluster, basta clicar em "Banco de Dados" no menu esquerdo e escolher "Carregar conjunto de dados de amostra", como mostrado na imagem:
Captura de tela demonstrando como carregar conjunto de dados de amostra
Legum: Carregando conjunto de dados no MongoDB Atlas.
Se tudo correr bem, após a importação, você verá nossos databases e collections exibidos conforme a imagem.
Captura de tela demonstrando bancos de dados e coleções importados
Legado: MongoDB Atlas com bancos de dados e coleções importados.

Criando o índice Atlas Search

Após importar as collections, a próxima etapa é criar um índice para a collection do Airbnb. Para fazer isso, selecione "Banco de dados" no menu lateral em "Deployment," Go para a guia "Atlas Search" e clique em " Editor JSON ," conforme mostrado na imagem:
Captura de tela demonstrando como criar um índice do Atlas Search
Imagem: MongoDB Atlas indicando a criação de um índice do Atlas Search .
Na próxima etapa,sample_airbnb selecione o banco de banco de dados e a listingsAndReviews coleção (a coleção do Airbnb). Em seguida, nomeie seu índice de "searchPlaces":
Captura de tela demonstrando como definir Propriedades do Índice
Mapear: MongoDB Atlas indicando a criação de uma propriedade de índice do Atlas Search
Observe que estamos usando Mapeamentos dinâmicos por simplificação, o que permite que o Atlas Search indexe automaticamente os campos dos tipos suportados em cada documento. Para obter mais detalhes, sugere-se verificar Definir Mapeamentos de Campo
Se tudo correr bem, o índice" searchPlaces" será criado com sucesso e você poderá visualizá-lo conforme mostrado na imagem abaixo:
Captura de tela demonstrando o Índice de Atlas Search criado
Legum: Tela mostrando o índice criado do Atlas Search

Testando nosso índice no MongoDB Compass

Para testar nosso índice, precisamos criar um agregação pipeline. Embora existam vários métodos para testar isso, usaremos o MongoDB Compass por conveniência. O MongoDB Compass é uma poderosa ferramenta de GUI que facilita o gerenciamento e a análise de dados do MongoDB . Ele fornece recursos para visualizar esquemas, criar queries e gerenciar dados por meio de uma interface intuitiva.
Precisamos configurar um pipeline de agregação para atender aos seguintes requisitos:
  1. Filtrar o camposummary por texto
  2. Garanta um mínimo number_of_reviews
Aqui está o pipeline de agregação que usaremos para testes:
1[
2 {
3 $search: {
4 index: "searchPlaces",
5 compound: {
6 filter: [
7 {
8 range: {
9 path: "number_of_reviews",
10 gte: 50
11 }
12 },
13 {
14 text: {
15 path: "summary",
16 query: "Istambun",
17 fuzzy: {
18 maxEdits: 2
19 }
20 }
21 }
22 ]
23 }
24 }
25 },
26 {
27 $limit: 5
28 },
29 {
30 $project: {
31 _id: 0,
32 name: 1,
33 summary: 1,
34 number_of_reviews: 1,
35 price: 1,
36 street: "$address.street",
37 }
38 }
39]
Vamos detalhar cada etapa:
  1. $search: o $search estágio usa os recursos do Atlas Search para executar uma pesquisa de texto completo com filtragem adicional.
    1. índice: "searchPlaces" especifica o índice de pesquisa a ser usado. Se o nome do índice fosse "padrão", não precisariamos especificá-lo aqui.
    2. composto: permite combinar vários critérios de pesquisa. A consulta composta aqui é usada para filtrar os resultados da pesquisa com base em critérios de texto e intervalo.
    3. filtro: contém uma array de critérios de filtro aplicados aos resultados da pesquisa.
    4. faixa: filtra documentos em que o number_of_reviews campo é maior ou igual 50 a.
    5. texto : o texto realiza uma pesquisa de texto summary completo no campo com a query "Istambun". A opção fuzzy com maxEdits: 2 permite a correspondência difusa, o que significa que pode corresponder termos semelhantes a "Istambun" com até duas edições de caracteres (inserções, exclusões ou substituições).
  2. $limit: Limita o número de documentos retornados pela query 5 a. Usar um limite é essencial para manter o desempenho.
  3. $ projeto: especifica quais campos incluir ou excluir no resultado final.
Basta executar este pipeline para obter os resultados. Veja:
Captura de tela demonstrando o MongoDB Compass com um aggregation pipeline executado
Legado: MongoDB Compass com uma aggregation pipeline executada

Construindo um aplicativo Kotlin

Nosso aplicação será desenvolvido em Kotlin com o Spring. Éimportante observar que não usaremos dados da Spring. Em vez disso, usaremos o Kotlin Sync Driver, especializado para comunicação entre o aplicação e o MongoDB. O objetivo do nosso aplicação é simples:
  • Forneça um endpoint que nos permita fazer solicitações e nos comunicar com o MongoDB Atlas.

Criando o projeto

Para fazer isso, usaremos a página oficial do Spring Initializer para criar nosso projeto:
Captura de tela demonstrando a página da web Spring Initializr
Gigo: Site do Spring Initializr para a criação do projeto
Como você pode ver, adicionei apenas a dependênciado Spring Web.

Adicionar dependência do driver MongoDB

A primeira coisa que vamos fazer é abrir o arquivobuild.gradle.kts e adicionar a dependênciamongodb-driver-kotlin-sync .
1dependencies {
2 implementation("org.mongodb:mongodb-driver-kotlin-sync:5.1.1")
3}
Captura de tela demonstrando o arquivo build.gradle.kts
Fragmento: build.gradle.kts com a dependência mongodb-driver-kotlin-sync adicionada.

Estabelecendo uma conexão

Para estabelecer nossa conexão, precisamos seguir estas etapas. Primeiro, atualize o arquivoapplication.properties com os valores exigidos.
1spring.application.name=Airbnb Searcher
2spring.data.mongodb.uri=mongodb+srv://user:pass@cluster0.cluster.mongodb.net/
3spring.data.mongodb.database=sample_airbnb
Aviso: não se lembre de atualizar o URI para corresponder à sua conexão do MongoDB.
Em seguida, criaremos uma classeMongoConfig dentro do diretórioapplication.config para configurar a conexão quando nosso aplicativo iniciar.
1package com.mongodb.searcher.application.config
2
3import com.mongodb.kotlin.client.MongoClient
4import com.mongodb.kotlin.client.MongoDatabase
5import org.springframework.beans.factory.annotation.Value
6import org.springframework.context.annotation.Bean
7import org.springframework.context.annotation.Configuration
8
9@Configuration
10class MongoConfig {
11
12 @Value("\${spring.data.mongodb.uri}")
13 lateinit var uri: String
14
15 @Value("\${spring.data.mongodb.database}")
16 lateinit var databaseName: String
17
18 @Bean
19 fun getMongoClient(): MongoClient {
20 return MongoClient.create(uri)
21 }
22
23 @Bean
24 fun mongoDatabase(mongoClient: MongoClient): MongoDatabase {
25 return mongoClient.getDatabase(databaseName)
26 }
27}
Ideal, definimos nossa classeMongoConfig, que usará os valores de application.properties. Agora, crie a classe AirbnbEntity dentro do pacoteresources :
1package com.mongodb.searcher.resources
2
3import com.mongodb.searcher.domain.Airbnb
4import org.bson.codecs.pojo.annotations.BsonId
5import org.bson.codecs.pojo.annotations.BsonProperty
6import org.bson.types.Decimal128
7
8data class AirbnbEntity(
9 @BsonId val id: String,
10 val name: String,
11 val summary: String,
12 val price: Decimal128,
13 @BsonProperty("number_of_reviews")
14 val numbersOfReviews: Int,
15 val address: Address
16) {
17 data class Address(
18 val street: String,
19 val country: String,
20 @BsonProperty("country_code")
21 val countryCode: String
22 )
23
24 fun toDomain(): Airbnb {
25 return Airbnb(
26 id = id,
27 name = name,
28 summary = summary,
29 price = price,
30 numbersOfReviews = numbersOfReviews,
31 street = address.street
32 )
33 }
34}

Criando o repositório

Agora, vamos criar nossa classe que utilizará o índice do Atlas Search. Para fazer isso, crie a classeAirbnbRepository dentro do pacoteresources .
1package com.mongodb.searcher.resources
2
3import com.mongodb.client.model.Aggregates
4import com.mongodb.client.model.Projections
5import com.mongodb.client.model.search.FuzzySearchOptions
6import com.mongodb.client.model.search.SearchOperator
7import com.mongodb.client.model.search.SearchOptions
8import com.mongodb.client.model.search.SearchPath
9import com.mongodb.kotlin.client.MongoDatabase
10import org.slf4j.LoggerFactory
11import org.springframework.stereotype.Repository
12
13@Repository
14class AirbnbRepository(
15 private val mongoDatabase: MongoDatabase
16) {
17 companion object {
18 private val logger = LoggerFactory.getLogger(AirbnbRepository::class.java)
19 private const val COLLECTION = "listingsAndReviews"
20 }
21 fun find(query: String, minNumberReviews: Int): List<AirbnbEntity> {
22 val collection = mongoDatabase.getCollection<AirbnbEntity>(COLLECTION)
23
24 return try {
25 collection.aggregate(
26 listOf(
27 createSearchStage(query, minNumberReviews),
28 createLimitStage(),
29 createProjectionStage()
30 )
31 ).toList()
32 } catch (e: Exception) {
33 logger.error("An exception occurred when trying to aggregate the collection: ${e.message}")
34 emptyList()
35 }
36 }
37
38 private fun createSearchStage(query: String, minNumberReviews: Int) =
39 Aggregates.search(
40 SearchOperator.compound().filter(
41 listOf(
42 SearchOperator.numberRange(SearchPath.fieldPath("number_of_reviews"))
43 .gte(minNumberReviews),
44 SearchOperator.text(SearchPath.fieldPath(AirbnbEntity::summary.name), query)
45 .fuzzy(FuzzySearchOptions.fuzzySearchOptions().maxEdits(2))
46 )
47 ),
48 SearchOptions.searchOptions().index("searchPlaces")
49 )
50 private fun createLimitStage() =
51 Aggregates.limit(5)
52
53
54 private fun createProjectionStage() =
55 Aggregates.project(
56 Projections.fields(
57 Projections.include(
58 listOf(
59 AirbnbEntity::name.name,
60 AirbnbEntity::id.name,
61 AirbnbEntity::summary.name,
62 AirbnbEntity::price.name,
63 "number_of_reviews",
64 AirbnbEntity::address.name
65 )
66 )
67 )
68 )
69}
Vamos analisar o método find.
Como você pode ver, o método espera uma string de query e um minNumberReviewsint e retorna uma lista de AirbnbEntity. Essa lista é gerada por meio de um pipeline de agregação, que consiste em três estágios:
  1. Estágio de pesquisa : Utiliza o $search operador para filtrar documentos com base na query e no número mínimo de revisões.
  2. Estágio limite: restringe o resultado definido a um número máximo de documentos.
  3. Estágio de projeção: Especifica quais campos incluir nos documentos devolvidos (esse estágio é opcional e incluído aqui apenas para ilustrar como usá-lo).
Aviso: dependendo do cenário, adicionar estágios após o estágio$searchpode afetar drasticamente o desempenho do aplicativo. Para obter mais detalhes, consulte nossos Docs sobre considerações de desempenho.

Criar um serviço

Para continuar com nosso projeto, vamos criar um pacote domaincom duas classes. O primeiro será o nossoAirbnb.
1package com.mongodb.searcher.domain
2
3import org.bson.codecs.pojo.annotations.BsonId
4import org.bson.codecs.pojo.annotations.BsonProperty
5import org.bson.types.Decimal128
6
7data class Airbnb(
8 @BsonId val id: String,
9 val name: String,
10 val summary: String,
11 val price: Decimal128,
12 @BsonProperty("number_of_reviews")
13 val numbersOfReviews: Int,
14 val street: String
15)
Em seguida, nosso AirbnbService:
1package com.mongodb.searcher.domain
2
3import com.mongodb.searcher.resources.AirbnbRepository
4import org.springframework.stereotype.Service
5
6@Service
7class AirbnbService(
8 private val airbnbRepository: AirbnbRepository
9) {
10
11 fun find(query: String, minNumberReviews: Int): List<Airbnb> {
12 require(query.isNotEmpty()) { "Query must not be empty" }
13 require(minNumberReviews > 0) { "Minimum number of reviews must not be negative" }
14
15 return airbnbRepository.find(query, minNumberReviews).map { it.toDomain() }
16 }
17}
Essa classe é responsável por validar nossas entradas e acessar o repositório.

Criando um controlador

Para habilitar a comunicação REST, crie a classeAirbnbController dentro do pacoteapplication.web :
1package com.mongodb.searcher.application.web
2
3import com.mongodb.searcher.domain.Airbnb
4import com.mongodb.searcher.domain.AirbnbService
5import org.springframework.web.bind.annotation.GetMapping
6import org.springframework.web.bind.annotation.RequestParam
7import org.springframework.web.bind.annotation.RestController
8
9@RestController
10class AirbnbController(
11 private val airbnbService: AirbnbService
12) {
13
14 @GetMapping("/airbnb/search")
15 fun find(
16 @RequestParam("query") query: String,
17 @RequestParam("minNumberReviews") minNumberReviews: Int
18 ): List<Airbnb> {
19 return airbnbService.find(query, minNumberReviews)
20 }
21}

Estrutura final do aplicativo

A estrutura final da pasta deve ser semelhante à da imagem:
Captura de tela demonstrando a estrutura do aplicativo.
Leg: Estrutura do aplicativo

Executando o aplicativo

Basta navegar até o diretório do projeto e executar:
1./gradlew bootRun
Em seguida, basta acessar o endpoint fornecendo os argumentos necessários. Abaixo está um exemplo:
1curl --location 'http://localhost:8080/airbnb/search?query=Istambun&minNumberReviews=50'
Captura de tela demonstrando a solicitação de pesquisa do Postman Atlas
Mapear: Solicitação de pesquisa do Atlas Atlas do Postman

Conclusão

Neste tutorial, criamos um aplicativo Spring Boot baseado em Kotlin que usa o MongoDB Atlas Atlas Search para encontrar listagens do Airbnb de forma eficiente. Demonstramos como criar um índice do Atlas Search e implementar um aggregation pipeline para filtrar e pesquisar dados.
Enquanto nos concentramos na correspondência difusa e na filtragem de contagem de avaliações, o MongoDB Atlas Atlas Search oferece muitos outros recursos avançados, como pontuação personalizada e análise avançada de texto.
Explorar estes recursos adicionais pode melhorar ainda mais a funcionalidade do Atlas Search e fornecer resultados ainda mais refinados. O exemplo de código-fonte usado nesta série está disponível em Github.
Para obter mais detalhes sobre o Atlas Search, veja o artigo Explorando recursos de pesquisa com o Atlas Search .
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.
Iniciar a conversa

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Início rápido

Integração do Atlas Search com o BuildSship


Oct 15, 2024 | 4 min read
Tutorial

Como construir um gráfico animado da linha do tempo com MongoDB Charts Embedding SDK


Dec 13, 2023 | 6 min read
Tutorial

Além do básico: aprimorando a API Kotlin Ktor com pesquisa vetorial


Sep 18, 2024 | 9 min read
Tutorial

Como distribuir um aplicativo no Kubernetes com o MongoDB Atlas Operator


Jan 13, 2025 | 9 min read
Sumário