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 .

Junte-se a nós no Amazon Web Services re:Invent 2024! Saiba como usar o MongoDB para casos de uso de AI .
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Produtoschevron-right
Atlaschevron-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 reino. Encontrar algo assim pode parecer difícil, não é mesmo? No entanto, há uma maneira de o Atlas Search obter informações com precisão usando o Atlas Search.
Neste tutorial, aprenderemos a criar um aplicativo em Kotlin que utiliza o Atlas Search de texto completo em um banco 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 aplicativoKotlin 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 camposummaryda collection para executar uma Atlas Search 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 do Atlas Search 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 uma correspondência aproximada e variações de manuseio nos termos do Atlas Search.
  • Faixa: exploraremos o operador rangeespecificamente com a condiçãogte (maior ou iguala) para o camponumber_of_reviews. Isso nos permitirá fazer query e filtrar com base nas contagens de avaliações de forma eficaz.
  • Composto: O operadorcompound será utilizado para combinar as queriestext fuzzy e range em uma Pesquisa Atlas mais complexa e refinada. Isso demonstrará como mesclar múltiplos critérios para uma funcionalidade mais sofisticada do Atlas Search.
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 doAirbnb. 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, selecione o banco de dadossample_airbnb e a coleçãolistingsAndReviews(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 aggregation 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. $Atlas Search: o estágio$searchusa os recursos do MongoDB Atlas Atlas Search para executar uma Atlas Search de texto completo com filtragem adicional.
    1. índice: "searchPlaces" especifica o índice do Atlas Search 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 do Atlas Search. A query composta aqui é usada para filtrar os resultados do Atlas Search com base em critérios de texto e intervalo.
    3. filtro: contém uma array de critérios de filtro aplicados aos resultados do Atlas Search.
    4. faixa: filtra documentos em que o camponumber_of_reviews é maior ou igual a 50.
    5. texto: o texto executa uma Pesquisa do Atlas de texto completo no campo summary com a consulta "Istambun". A opção difusa com maxEdits: 2 permite a correspondência difusa, o que significa que ele pode corresponder termos semelhantes a "Istambun" com até a duas edições de caracteres (inserções, exclusões ou substituições).
  2. $limit: Limita o número de documentos retornados pela query para 5. Usar um limite é essencial para manter o desempenho.
  3. $project: 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 aplicativo 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 aplicativo e o MongoDB. O objetivo do nosso aplicativo é 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 Atlas Search: Utiliza o operador$search 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 mais informações sobre o Atlas Search, veja o artigoExplorando os recursos do Atlas Search 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
Tutorial

Criando gráficos de AI com Rivet e MongoDB Atlas Vector Search para potencializar aplicativos de AI


Sep 18, 2024 | 10 min read
Artigo

Usar o Atlas Search do Java


Jul 14, 2023 | 13 min read
Tutorial

Trabalhando com MongoDB Charts e o novo SDK para JavaScript


Apr 02, 2024 | 10 min read
Tutorial

Transmissão de dados do MongoDB para o BigQuery usando conectores Confluent


Jul 11, 2023 | 4 min read
Sumário