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
Idiomaschevron-right
Swiftchevron-right

Crie uma ferramenta de linha de comando com Swift e MongoDB

Michael Lynn13 min read • Published Feb 17, 2022 • Updated Sep 11, 2024
MongoDBSwift
APLICATIVO COMPLETO
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse exemplo de código
star-empty
star-empty
star-empty
star-empty
star-empty
social-githubVer código

Sumário

Introdução

Construir algo com as próprias mãos dá uma sensação de satisfação, como poucas outras tarefas. Mas realmente não há comparação com a sensação que você tem ao criar algo que não apenas realiza a tarefa imediata em questão, mas também permite que você realize a mesma tarefa com mais eficiência no futuro. Ou, melhor ainda, quando outra pessoa pode usar o que você criou para realizar suas tarefas com mais facilidade. Isso é o que faremos hoje. Vamos construir algo que automatize o processo de importação de dados para o MongoDB.
Um programa executável é poderoso porque é independente e transportável. Não há necessidade de compilá-lo ou garantir que outros elementos estejam presentes no ambiente. Ele apenas corre. Você pode compartilhá-lo com outras pessoas e, supondo que elas tenham um sistema relativamente semelhante, ele também será executado para elas. Vamos nos concentrar em atingir nosso objetivo usando o Swift, a linguagem de programação fácil de aprender da Apple. Também mostraremos o uso do nosso novo MongoDB Swift Driver, que permite criar, ler, atualizar e excluir dados em um MongoDB database.

TL;DR:

Em vez disso, um vídeo demonstrando esse conteúdo? Confira o vídeo do YouTube em que meu colega Nic RaBoy e eu conversamos sobre esse mesmo conteúdo.

Objetivos

Aqui estão os objetivos deste artigo.
  1. Aumente sua familiaridade com o MongoDB Atlas
  2. Apresentar você ao Swift Driver do MongoDB
  3. Apresentar você ao Swift Package Manager
Ao final deste artigo, se tivermos atingido nossas metas, você será capaz de fazer o seguinte:
  1. Use o Xcode para começar a fazer experiências com o Swift
    • Criar um projeto básico.
    • Integre o MongoDB Swift Driver em seu projeto
    • Crie um executável no seu Mac.

Pré-requisitos

Antes de começarmos, vamos esclarecer algumas das coisas que você precisará ter para começar.
  • Um Mac e macOS (não um dispositivo iOS). Você pode estar lendo isto em seu PC com Windows ou um iPad. Pessoal, este tutorial foi escrito para que você possa acompanhar em sua máquina Mac: macbook, macbook pro, imac etc. Você pode querer conferir o macincloud se estiver interessado em uma experiência virtual com o Mac.
  • Xcode. Você deve ter o Xcode instalado - Visite a App Store da Apple para instalar no seu Mac.
  • Swift instalado - Visite o Site do Desenvolvedor da Apple para saber mais.
  • Acesso a um MongoDB database – Visite MongoDB Atlas para começar gratuitamente. Leia mais sobre MongoDB Atlas.
Versão do Xcode 11.6
Se você não tem muita experiência com o Xcode ou o desenvolvimento de aplicativos MacOS, confira os guias no Hub do Desenvolvedor da Apple. Começar é muito fácil e é grátis!

O que construiremos?

A tarefa que estou tentando automatizar envolve a importação de dados para um banco de MongoDB database. Antes de avançarmos muito no caminho da criação de uma solução, vamos documentar nosso conjunto de requisitos para o que criaremos.
De CSV para MongoDB

Visão geral das etapas

Aqui está um resumo rápido das etapas em que trabalharemos para concluir nossa tarefa.
  1. Inicie um cluster do Atlas.
  2. Adicione um usuário/senha de banco de dados e uma entrada de exceção de rede para que você possa acessar seu banco de dados a partir do seu endereço IP.
  3. Crie um projeto Swift usando o Swift Package Manager (swift package init --type=executable)
  4. Gerar um projeto Xcode usando o Swift Package Manager (swift package generate-xcodeproj)
  5. Crie um (for loop) usando (String) para acessar e imprimir os dados em seu arquivoexample.csv. (Consulte csvread.swift)
  6. Modifique seu pacote para obter o MongoDB Swift Driver. (Consulte Package.swift)
  7. Teste.(swift build; swift run) Erros? Consulte a seção de perguntas frequentes abaixo.
  8. Modifique seu código para incorporar o driver MongoDB Swift e escreva documentos. (Veja Fontes/linha de comando-swift-mongodb/main.swift)
  9. Teste.(swift build; swift run) Erros? Consulte a seção de perguntas frequentes abaixo.
  10. Criar executável e liberar.(swift package release)

Requisitos para solução

  1. A solução deve importar um conjunto de dados que comece no formato CSV (ou tabular/excel) para um MongoDB database existente.
  2. Cada linha dos dados no CSV deve se tornar um documento separado no MongoDB database. Além disso, cada novo documento deve incluir um novo campo com a data/hora de importação.
  3. Deve ser feito com o mínimo de conhecimento do MongoDB , ou seja, alguém com relativamente pouca experiência e conhecimento do MongoDB deve ser capaz de executar a tarefa em alguns minutos.
Poderemos simplesmente usar o mongoimport com a seguinte linha de comando:
1mongoimport --host localhost:27017 --type csv --db school --collection students --file example.csv --headerline
Se você estiver familiarizado com o MongoDB, a linha de comando acima não parecerá nada complicada. No entanto, isso não atenderá aos nossos requisitos pelos seguintes motivos:
  • Requisito 1: Aprovado - Isso resultará na importação de dados para o MongoDB.
  • Requisito 2: Falha - Embora cada linha se torne um documento separado, não obteremos nosso campo de data adicional nesses documentos.
  • Requisito 3: Fail - Embora a sintaxe aqui possa parecer bastante simples se você já tiver usado o MongoDB antes, para um novato, ela pode ser um pouco confusa. Por exemplo, estou usando localhost aqui... quando executarmos esse executável em outro host, precisaremos substituí-lo pelo nome real do host do nosso MongoDB database. A sintaxe do comando ficará um pouco mais complexa quando isso acontecer.
Então, como criaremos algo que atenda a todos os nossos requisitos?
Podemos construir um executável de linha de comando que usa o MongoDB Swift Driver para realizar a tarefa. Construir um programa para realizar nossa tarefa nos permite abstrair grande parte da complexidade associada à nossa tarefa. Felizmente, há um driver para o Swift e usá-lo para ler CSV, manipulá-los e escrevê-los em um MongoDB database é realmente simples.
CSV para MongoDB

Iniciando seu cluster de banco de dados no Atlas

Você precisará criar um novo cluster e carregá-lo com dados de amostra. Meu colega Maxime Beugnet criou um tutorial em vídeo para ajudar você, mas também explico as etapas abaixo:
  • Clique em "Comece grátis" na página inicial do MongoDB.
  • Insira seus detalhes cadastre-se com sua conta do Google, se tiver uma.
  • Aceite os Termos de Serviço
  • Crie um cluster Starter.
    • Selecione o provedor de nuvem onde você gostaria de armazenar seu banco de dados MongoDB.
    • Escolha uma região que faça sentido para você.
    • Você pode alterar o nome do cluster, se quiser. Chamei o meu de "MyFirstCluster".
Depois que seu cluster for iniciado, adicione uma entrada deexceção de rede para seu IP atual e, em seguida,adicione um nome de usuário e senha de banco de dados. Anote o nome de usuário e a senha. Você precisará deles em breve.

Configurando o projeto

Começaremos nossa jornada criando um pacote Swift usando o Swift Package Manager. Essa ferramenta nos dará um projeto de modelo e estabelecerá a estrutura de diretórios e alguns andaimes necessários para começar. Vamos usar a ferramenta de linha de comando swift com o subcomandopackage.
Existem várias variações que podemos usar. Antes de pular, vamos dar um exemplo da diferença em algumas das bandeiras.
1swift package init
Esta variação mais básica nos fornecerá um projeto de uso geral. Mas, como estamos criando um MacOS executável, vamos adicionar o sinalizador--type para indicar o tipo de projeto em que estamos trabalhando.
1swift package init --type=executable
Isso criará um projeto que define o "produto" de uma construção -- que é, em essência, nosso executável. Lembre-se de que, se você estiver criando um executável, normalmente para o Swift do lado do servidor, convém incorporar o sinalizador--type=executable .
O Xcode é onde a maioria dos desenvolvedores iOS e Apple em geral escreve e mantém o código, então vamos preparar um projeto para que possamos usar o Xcode também. Agora que já temos nossa estrutura básica de projeto pronta, vamos criar um projeto do Xcode no qual poderemos modificar nosso código.
Para criar um projeto Xcode, basta executar o seguinte comando:
1swift package generate-xcodeproj
Em seguida, podemos abrir o arquivo.xcproject. Seu mac deve abrir automaticamente o Xcode como resultado de tentar abrir um arquivo do Xcode Project.
1open <your project name>.xcodeproj/ # change this to the name that was created by the previous command.

Olhando para nossos dados

Com a estrutura do nosso projeto pronta, vamos nos concentrar nos dados que manipularemos com o nosso executável. Vamos dar uma olhada nos dados brutos primeiro. Digamos que haja uma lista de alunos que saem todos os meses e que eu preciso colocar em meu banco de dados. Pode ser mais ou menos assim:
1firstname,lastname,assigned
2Michael,Basic,FALSE
3Dan,Acquilone,FALSE
4Eli,Zimmerman,FALSE
5Liam,Tyler,FALSE
6Jane,Alberts,FALSE
7Ted,Williams,FALSE
8Suzy,Langford,FALSE
9Paulina,Stern,FALSE
10Jared,Lentz,FALSE
11June,Gifford,FALSE
12Wilma,Atkinson,FALSE
Neste exemplo de dados, temos 3 campos básicos de informações: Nome, Sobrenome e um valor booleano indicando se o aluno foi ou não atribuído a uma classe específica.
Queremos obter esses dados do formulário atual (CSV) em documentos dentro do banco de dados e, ao longo do caminho, adicionar um campo para registrar a data em que o documento foi importado. Isso exigirá que leiamos o arquivo CSV dentro de nosso aplicativo Swift. Antes de prosseguir, certifique-se de ter dados semelhantes em um arquivo para o qual você sabe o caminho. Estaremos criando algum código ao lado para acessar esse arquivo com Swift.
Quando terminarmos, os dados ficarão assim, representados em um JSON document:
1{
2"_id": {
3 "$oid": "5f491a3bf983e96173253352" // this will come from our driver.
4},
5"firstname": "Michael",
6"lastname": "Basic",
7"date": {
8 "$date": "2020-08-28T14:52:43.398Z" // this will be set by our Struct default value
9},
10"assigned": false
11}
Para colocar as linhas e campos de nomes no MongoDB, usaremos a classeStringintegrada do Swift. Este é um utilitário poderoso que pode fazer de tudo, desde ler o conteúdo de um arquivo até interpolar variáveis incorporadas e fazer comparações entre dois ou mais conjuntos de strings. O método da classeconcernsOfFile da classe String acessará o arquivo com base em um caminho de arquivo que fornecemos, abrirá o arquivo e nos permitirá acessar seu conteúdo. Veja como nosso código poderia ficar se tivéssemos apenas que percorrer o arquivo CSV e imprimir as linhas que ele contém.
Você pode ficar tentado a apenas copiar/cole o código abaixo. Sugiro que você digite à mão ... lendo na tela. Isso permitirá que você experimente o poder da correção automática e da sugestão de código dentro do Xcode. Além disso, certifique-se de modificar o valor da variávelpath para apontar para o local onde você coloca seu arquivoexample.csv.
1import Foundation
2
3let path = "/Users/mlynn/Desktop/example.csv" // change this to the path of your csv file
4do {
5 let contents = try String(contentsOfFile: path, encoding: .utf8)
6 let rows = contents.components(separatedBy: NSCharacterSet.newlines)
7 for row in rows {
8 if row != "" {
9 print("Got Row: \(row)")
10 }
11 }
12}
Vamos dar uma olhada no que está acontecer aqui.
  • Linha 1: usaremos a biblioteca principal do Foundation. Isso nos dá acesso a alguns métodos básicos de string, caracteres e comparação. A declaração de importação nos dá acesso a bibliotecas e módulos nativos e de terceiros.
  • Linha 3: codifique uma variável de caminho para o arquivo CSV.
  • Linhas 6a7: use o método String para acessar o conteúdo do arquivo CSV.
  • Linha 8: Percorra cada linha em nosso arquivo e exiba o conteúdo.
Para executar este exemplo simples, vamos abrir o arquivomain.swift que o comando swift package init criou para nós. Para editar este arquivo, no Xcode, Para começar, vamos abrir o arquivo principal.swift que nosso comando swift package init criou para nós. Para editar este arquivo, no Xcode, percorra a árvore de pastas em Project->Sources-Project name... e abra main.swift. Substitua o simples hello world pelo código acima.
Executando isso em nosso arquivo example.csv, você verá algo parecido com o seguinte resultado. Usaremos os comandosswift build e swift run.
CSV para MongoDB

Integrando o driver Swift do MongoDB

Com esta construção básica implementada, podemos agora começar a incorporar o código necessário para inserir um documento em nosso banco de dados para cada linha de dados no arquivo csv. Vamos começar configurando o Swift Package Manager para integrar o Swift Driver do MongoDB.
Arquivo Package.swift
Navegue no explorador de projetos para encontrar o arquivo Package.swift. Substitua o conteúdo pelo arquivo Package.swift do repositório:
1// swift-tools-version:5.2
2// The swift-tools-version declares the minimum version of Swift required to build this package.
3import PackageDescription
4
5let package = Package(
6 name: "csvimport-swift",
7 platforms: [
8 .macOS(.v10_15),
9 ],
10 dependencies: [
11 .package(url: "https://github.com/mongodb/mongo-swift-driver.git", from: "1.0.1"),
12 ],
13 targets: [
14 .target(
15 name: "csvimport-swift",
16 dependencies: [.product(name: "MongoSwiftSync", package: "mongo-swift-driver")]),
17 .testTarget(
18 name: "csvimport-swiftTests",
19 dependencies: ["csvimport-swift"]),
20 ]
21)
Se você não está familiarizado com o Swift Package Manager, faça um desvio e leia aqui.
Estamos incluindo uma declaração informando ao Swift Package Manager que estamos criando esse executável para um conjunto específico de versões do MacOS.
1platforms: [
2 .macOS(.v10_15)
3],
Dica: se você deixar esta declaração de fora, receberá uma mensagem informando que o pacote foi projetado para ser criado para MacOS 10.10 ou similar.
Em seguida, incluímos referências aos pacotes necessários em nosso software para inserir e manipular dados do MongoDB. Neste exemplo, nos concentraremos em uma implementação assíncrona. Ou seja, o mongo-swift-driver.
Agora que incluímos nossas dependências, vamos construir o projeto. Construa o projeto com frequência para detectar quaisquer erros que possa ter introduzido inadvertidamente no início.
1swift package build
Você deverá obter uma resposta semelhante à seguinte:
1[3/3] Linking cmd
Agora vamos modificar nosso projeto de programa básico para usar nosso driver MongoDB.
1import Foundation
2import MongoSwiftSync
3
4var murl: String = "mongodb+srv://<username>:\(ProcessInfo.processInfo.environment["PASS"]!)@myfirstcluster.zbcul.mongodb.net/<dbname>?retryWrites=true&w=majority"
5let client = try MongoClient(murl)
6
7let db = client.db("students")
8let session = client.startSession(options: ClientSessionOptions(causalConsistency: true))
9
10struct Person: Codable {
11 let firstname: String
12 let lastname: String
13 let date: Date = Date()
14 let assigned: Bool
15 let _id: BSONObjectID
16}
17
18let path = "/Users/mlynn/Desktop/example.csv"
19var tempAssigned: Bool
20var count: Int = 0
21var header: Bool = true
22
23let personCollection = db.collection("people", withType: Person.self)
24
25do {
26 let contents = try String(contentsOfFile: path, encoding: .utf8)
27 let rows = contents.components(separatedBy: NSCharacterSet.newlines)
28 for row in rows {
29 if row != "" {
30 var values: [String] = []
31 values = row.components(separatedBy: ",")
32 if header == true {
33 header = false
34 } else {
35 if String(values[2]).lowercased() == "false" || Bool(values[2]) == false {
36 tempAssigned = false
37 } else {
38 tempAssigned = true
39 }
40 try personCollection.insertOne(Person(firstname: values[0], lastname: values[1], assigned: tempAssigned, _id: BSONObjectID()), session: session)
41 count.self += 1
42 print("Inserted: \(count) \(row)")
43
44 }
45 }
46 }
47}
A linha 2 importa o driver de que precisaremos (mongo-swift).
Em seguida, configuramos o driver.
1var murl: String = "mongodb+srv://<username>:\(ProcessInfo.processInfo.environment["PASS"]!)@myfirstcluster.zbcul.mongodb.net/<dbname>?retryWrites=true&w=majority"
2let client = try MongoClient(murl)
3
4let db = client.db("students")
5let session = client.startSession(options: ClientSessionOptions(causalConsistency: true))
Lembre-se de substituir <username> pelo usuário que você criou no Atlas.
Para ler e escrever dados de e para MongoDB no Swift, precisaremos aproveitar uma estrutura Codable. Os codeables são uma funcionalidade surpreendente do Swift e definitivamente úteis para escrever código que gravará dados no MongoDB. Codables é, na verdade, um alias para dois protocolos: Encodablee Decodable. Quando deixamos nosso Struct conformidade com o protocolo Codable, podemos codificar nossos dados de string em JSON e depois decodificá-los de volta em um Structsimples usando JSONEncoder e JSONDecoder, respectivamente. Vamos precisar dessa estrutura porque o formato usado para armazenar dados no MongoDB é ligeiramente diferente da representação que você vê dessa estrutura de dados no Swift. Criaremos uma estrutura para descrever como deve ser o esquema de documentos dentro do MongoDB. Veja como deve ser o nosso esquema Struct:
1struct Code: Codable {
2 let code: String
3 let assigned: Bool
4 let date: Date = Date()
5 let _id: BSONObjectID
6}
Observe que temos todos os elementos do nosso arquivo CSV e um campo de data.
Também precisaremos de algumas variáveis temporárias que usaremos ao processar os dados. count e uma variável temporária especial que usarei quando determino se um aluno está ou não designado para umatempAssigned classe... . Por fim, neste bloco de código, criarei uma variável para armazenar o estado da nossa posição no arquivo . ocabeçalho será definido como verdadeiro inicialmente porque queremos pular a primeira linha de dados. É aí que ficam os cabeçalhos das colunas .
1let path = "/Users/mlynn/Desktop/example.csv"
2var tempAssigned: Bool
3var count: Int = 0
4var header: Bool = true
Agora podemos criar uma referência para a collection em nosso MongoDB database que usaremos para armazenar os dados dos alunos. Na falta de um nome melhor, estou chamando o meu personCollection. Além disso, observe que estamos fornecendo um link de volta para nosso Struct utilizando o argumentowithType para o método de collection. Isso garante que o motorista saiba com que tipo de dados estamos lidando.
1let personCollection = db.collection("people", withType: Person.self)
O próximo bit de código está no centro da nossa tarefa. Vamos percorrer cada linha e criar um documento. Comentei e expliquei cada linha in-line.
1let contents = try String(contentsOfFile: path, encoding: .utf8) // get the contents of our csv file with the String built-in
2let rows = contents.components(separatedBy: NSCharacterSet.newlines) // get the individual rows separated by newline characters
3for row in rows { // Loop through all rows in the file.
4 if row != "" { // in case we have an empty row... skip it.
5 var values: [String] = [] // create / reset the values array of type string - to null.
6 values = row.components(separatedBy: ",") // assign the values array to the fields in the row of data
7 if header == true { // if it's the first row... skip it and.
8 header = false // Set the header to false so we do this only once.
9 } else {
10 if String(values[2]).lowercased() == "false" || Bool(values[2]) == false {
11 tempAssigned = false // Above: if its the string or boolean value false, so be it
12 } else {
13 tempAssigned = true // otherwise, explicitly set it to true
14 }
15 try personCollection.insertOne(Person(firstname: values[0], lastname: values[1], assigned: tempAssigned, _id: BSONObjectID()), session: session)
16 count.self += 1 // Above: use the insertOne method of the collection class form
17 print("Inserted: \(count) \(row)") // the mongo-swift-driver and create a document with the Person ``Struct``.
18 }
19 }
20 }

Conclusão

A importação de dados é um desafio comum. Ainda mais comum é quando queremos automatizar a tarefa de inserção ou manipulação de dados com o MongoDB. Neste tutorial, expliquei como você pode começar a usar o Swift e realizar a tarefa de simplificar a importação de dados criando uma ferramenta executável de linha de comando que pode ser compartilhada com um colega para que ele possa importar dados para você. Embora esse exemplo seja bastante simples em termos de como ele resolve o problema em questão, você certamente pode dar o próximo passo e começar a desenvolvê-lo para dar suporte a argumentos de linha de comando e até mesmo usá-lo não apenas para inserir dados, mas também para remover e mesclar ou atualizar dados.
Preparei uma seção abaixo intitulada Solução de problemas caso você se depare com alguns erros comuns. Fizemos o possível para pensar em todos os problemas usuais que você pode encontrar. No entanto, se você encontrar outro problema, informe-me. A melhor maneira de fazer isso é Inscrever-se na MongoDB Community e não deixar de visitar a seção de Drivers e ODMs.

Recursos

Solução de problemas

Use esta seção para ajudar a resolver alguns problemas comuns. Se você ainda tiver problemas depois de ler essas soluções comuns, visite-me na MongoDB Community.

Nenhum módulo desse tipo

Erro do Swift: Não existe tal módulo
Isso ocorre quando o Swift não conseguiu criar o módulomongo-swift-driver . Isso normalmente ocorre quando um desenvolvedor está tentando usar o Xcode e não especificou uma versão mínima do sistema operacional de destino. Revise a imagem anexa e observe a sequência de cliques para obter a configuração apropriada. Altere essa configuração para 10.15 ou superior.
Erro do Swift Nenhum módulo desse tipo

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse exemplo de código
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Tutorial

Construindo e hospedando continuamente nossa documentação do Swift DocC usando ações do Github e Netlify


Sep 17, 2024 | 6 min read
Notícias e Anúncios

Interrompendo o desenvolvimento do driver Swift do MongoDB


Sep 11, 2024 | 1 min read
Início rápido

Trabalhando com Change Streams do seu aplicativo Swift


Jan 25, 2023 | 4 min read
Tutorial

Adicionar Realm como uma dependência a um framework do iOS


Aug 12, 2024 | 4 min read
Tecnologias Utilizadas
Linguagens
Produtos
Sumário