MongoDB
Introdução
MongoDB é uma base de dados NoSQL orientada a documentos. Em vez de tabelas e linhas os dados são guardados em documentos no formato semelhante ao JSON, o que permite uma grande flexibilidade no modelo dos dados.
O Netuno oferece o recurso _mongo para a integração com o MongoDB, com uma abstração low-code sobre o cliente oficial do MongoDB para Java, disponível para as diversas linguagens de programação suportadas pelo Netuno: JavaScript, Python, Ruby, Kotlin e Groovy.
Antes de avançar, recomenda-se que saiba como criar serviços no Netuno, veja o tutorial REST - Serviços Web.
Um exemplo de implementação das operações apresentadas aqui está disponível no serviço de exemplo mongo.js que se localiza em:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
apps/demo/server/services/samples/javascript/mongo.js
apps/demo/server/services/samples/javascript/mongo.py
apps/demo/server/services/samples/javascript/mongo.rb
apps/demo/server/services/samples/javascript/mongo.kts
apps/demo/server/services/samples/javascript/mongo.groovy
Instalação do MongoDB
Com Docker
Assumindo que tem o Docker instalado, basta efetuar o download da imagem do MongoDB e iniciar um novo container:
docker pull mongo
docker run -d --name mongo -p 27017:27017 mongo
Desta forma o MongoDB fica acessível em localhost:27017 sem autenticação.
Para criar o utilizador da base de dados conforme a configuração da aplicação, execute:
docker exec -it mongo mongosh products_db --eval 'db.createUser({ user: "products_user", pwd: "12345678", roles: [{ role: "readWrite", db: "products_db" }] })'
Com Ubuntu
O MongoDB não está incluído nos repositórios oficiais do Ubuntu, portanto é necessário adicionar o repositório oficial antes da instalação:
sudo apt-get install gnupg curl
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] http://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org
Depois de instalado, pode iniciar o serviço com:
sudo systemctl start mongod
Com Windows
Execute o instalador descarregado e, no passo Service Configuration, ative Install MongoD as a Service para que o MongoDB arranque automaticamente. O MongoDB fica acessível em localhost:27017 sem autenticação.
Consulte a documentação oficial do MongoDB para outras distribuições e versões.
Configuração da Aplicação
A configuração das conexões do MongoDB é feita no ficheiro de configuração da aplicação, de acordo com o ambiente:
config/_development.json
Veja mais sobre os ficheiros de configuração da aplicação.
Dentro do ficheiro de configuração, adicione o bloco mongo, onde cada chave identifica uma conexão:
{
...
"mongo": {
"store": "mongodb://store_user:12345678@localhost/store_db",
"products": {
"username": "products_user",
"password": "12345678",
"host": "127.0.0.1",
"port": "27017",
"database": "products_db"
}
},
...
}
Uma conexão pode ser definida de duas formas:
- Como URL de conexão — o valor é simplesmente uma string, por exemplo
"mongodb://store_user:12345678@localhost/store_db". - Como objeto de configuração — com os campos:
url— se definido, é utilizado diretamente como URL de conexão, ignorando os outros campos.protocol— o protocolo da conexão, por defaultmongodb.usernameepassword— as credenciais de acesso.host— o endereço do servidor, por defaultlocalhost.port— a porta da conexão, por default27017.database— o nome da base de dados, por default o nome da chave da conexão.params— parâmetros adicionais da conexão acrescentados à URL, por exemplo{ "authSource": "admin" }. Só são aplicados quando a URL é construída a partir dos campos do objeto.
A conexão não tem de ser a base de dados principal da aplicação. Ao contrário da configuração
db, o blocomongoé independente e permite várias conexões em simultâneo.
Inicializar a Conexão
O primeiro passo é inicializar o cliente do MongoDB com o recurso _mongo.init(...), passando o nome da chave de configuração ou diretamente uma URL de conexão:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const mongo = _mongo.init("products")
mongo = _mongo.init("products")
mongo = _mongo.init("products")
val mongo = _mongo.init("products")
def mongo = _mongo.init("products")
Também pode inicializar a conexão diretamente com uma URL:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const mongo = _mongo.init("mongodb://localhost:27017/products_db")
const mongo = _mongo.init("mongodb://localhost:27017/products_db")
const mongo = _mongo.init("mongodb://localhost:27017/products_db")
const mongo = _mongo.init("mongodb://localhost:27017/products_db")
const mongo = _mongo.init("mongodb://localhost:27017/products_db")
Ao chamar
_mongo.init()sem argumentos é utilizada a chave de configuraçãodefault. É recomendado passar sempre o nome da chave ou a URL, para ficar explícita a conexão utilizada.
Base de Dados e Coleções
Com o cliente inicializado, obtenha a instância da base de dados com database("nome"). Em seguida pode criar coleções e aceder a uma coleção existente:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const db = mongo.database("products_db")
db.createCollection("product")
const collection = db.collection("product")
db = mongo.database("products_db")
db.createCollection("product")
collection = db.collection("product")
db = mongo.database("products_db")
db.createCollection("product")
collection = db.collection("product")
val db = mongo.database("products_db")
db.createCollection("product")
val collection = db.collection("product")
def db = mongo.database("products_db")
db.createCollection("product")
def collection = db.collection("product")
Pode testar a conexão com a base de dados com o ping(), e listar todas as coleções existentes com collectionNames():
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
db.ping()
const names = db.collectionNames()
db.ping()
names = db.collectionNames()
db.ping()
names = db.collectionNames()
db.ping()
val names = db.collectionNames()
db.ping()
final names = db.collectionNames()
Pode renomear uma coleção com o renameCollection(), passando o nome completo com a base de dados, ou o nome da base de dados e o novo nome da coleção em separado:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
collection.renameCollection("products_db.product_archive")
collection.renameCollection("archive_db", "product_archive")
collection.renameCollection("products_db.product_archive")
collection.renameCollection("archive_db", "product_archive")
collection.renameCollection("products_db.product_archive")
collection.renameCollection("archive_db", "product_archive")
collection.renameCollection("products_db.product_archive")
collection.renameCollection("archive_db", "product_archive")
collection.renameCollection("products_db.product_archive")
collection.renameCollection("archive_db", "product_archive")
Para remover uma coleção e todos os seus documentos, utilize o drop():
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
collection.drop()
collection.drop()
collection.drop()
collection.drop()
collection.drop()
Inserir Documentos
Os dados são representados com o recurso _val, através de _val.map() para documentos e _val.list() para listas de valores.
Inserir um único documento
Com insertOne() insere um documento e obtém o ID gerado:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const id = collection.insertOne(
_val.map()
.set("name", "Laptop")
.set("quantity", 22)
.set("price", 100)
.set("category", "computers")
)
id = collection.insertOne(
_val.map()
.set("name", "Laptop")
.set("quantity", 22)
.set("price", 100)
.set("category", "computers")
)
id = collection.insertOne(
_val.map()
.set("name", "Laptop")
.set("quantity", 22)
.set("price", 100)
.set("category", "computers")
)
val id = collection.insertOne(
_val.map()
.set("name", "Laptop")
.set("quantity", 22)
.set("price", 100)
.set("category", "computers")
)
def id = collection.insertOne(
_val.map()
.set("name", "Laptop")
.set("quantity", 22)
.set("price", 100)
.set("category", "computers")
)
Os documentos podem conter estruturas aninhadas, como listas e outros documentos:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
collection.insertOne(
_val.map()
.set("name", "Tablet")
.set("tags",
_val.list()
.add("promo")
.add("new")
)
.set("details",
_val.map()
.set("color", "blue")
.set("stock", 10)
)
)
collection.insertOne(
_val.map()
.set("name", "Tablet")
.set("tags",
_val.list()
.add("promo")
.add("new")
)
.set("details",
_val.map()
.set("color", "blue")
.set("stock", 10)
)
)
collection.insertOne(
_val.map()
.set("name", "Tablet")
.set("tags",
_val.list()
.add("promo")
.add("new")
)
.set("details",
_val.map()
.set("color", "blue")
.set("stock", 10)
)
)
collection.insertOne(
_val.map()
.set("name", "Tablet")
.set("tags",
_val.list()
.add("promo")
.add("new")
)
.set("details",
_val.map()
.set("color", "blue")
.set("stock", 10)
)
)
collection.insertOne(
_val.map()
.set("name", "Tablet")
.set("tags",
_val.list()
.add("promo")
.add("new")
)
.set("details",
_val.map()
.set("color", "blue")
.set("stock", 10)
)
)
Inserir múltiplos documentos
Com insertMany() insere vários documentos de uma só vez, recebendo a lista de IDs gerados:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const ids = collection.insertMany(
_val.list()
.add(
_val.map()
.set("name", "Smartphone")
.set("quantity", 18)
)
.add(
_val.map()
.set("name", "Monitor")
.set("quantity", 8)
)
)
ids = collection.insertMany(
_val.list()
.add(
_val.map()
.set("name", "Smartphone")
.set("quantity", 18)
)
.add(
_val.map()
.set("name", "Monitor")
.set("quantity", 8)
)
)
ids = collection.insertMany(
_val.list()
.add(
_val.map()
.set("name", "Smartphone")
.set("quantity", 18)
)
.add(
_val.map()
.set("name", "Monitor")
.set("quantity", 8)
)
)
val ids = collection.insertMany(
_val.list()
.add(
_val.map()
.set("name", "Smartphone")
.set("quantity", 18)
)
.add(
_val.map()
.set("name", "Monitor")
.set("quantity", 8)
)
)
def ids = collection.insertMany(
_val.list()
.add(
_val.map()
.set("name", "Smartphone")
.set("quantity", 18)
)
.add(
_val.map()
.set("name", "Monitor")
.set("quantity", 8)
)
)
Consultar Documentos
O método find() devolve um MongoFindIterable, a partir do qual obtém os documentos com all() (todos) ou first() (o primeiro, ou null se não houver nenhum).
Para obter todos os documentos da coleção:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const docs = collection.find().all()
const docs = collection.find().all()
const docs = collection.find().all()
const docs = collection.find().all()
const docs = collection.find().all()
Para consultar com um filtro, utilize a factory _mongo.filters():
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const docs = collection.find(
_mongo.filters().eq("name", "Laptop")
).all()
docs = collection.find(
_mongo.filters().eq("name", "Laptop")
).all()
docs = collection.find(
_mongo.filters().eq("name", "Laptop")
).all()
val docs = collection.find(
_mongo.filters().eq("name", "Laptop")
).all()
def docs = collection.find(
_mongo.filters().eq("name", "Laptop")
).all()
Filtros
A factory _mongo.filters() oferece os principais operadores de consulta do MongoDB:
| Operador | Descrição |
|---|---|
eq("campo", valor) | Igual ao valor. |
ne("campo", valor) | Diferente do valor. |
gt("campo", valor) | Maior que o valor. |
gte("campo", valor) | Maior ou igual ao valor. |
lt("campo", valor) | Menor que o valor. |
lte("campo", valor) | Menor ou igual ao valor. |
in("campo", valor1, valor2, ...) | Igual a qualquer um dos valores. |
nin("campo", valor1, valor2, ...) | Diferente de todos os valores. |
and(filtro1, filtro2, ...) | Corresponde a todos os filtros. |
or(filtro1, filtro2, ...) | Corresponde a pelo menos um dos filtros. |
not(filtro) | Não corresponde ao filtro. |
regex("campo", "padrão") | Corresponde à expressão regular. |
exists("campo") | O campo existe no documento. |
text("pesquisa") | Pesquisa de texto. |
type("campo", "tipo") | O campo é do tipo especificado. |
mod("campo", divisor, resto) | O resto da divisão do campo pelo divisor é igual ao valor. |
where("expressão") | Corresponde aos documentos que satisfazem uma expressão JavaScript, por exemplo "this.price > 100". |
size("campo", n) | O campo de matriz tem exatamente n elementos. |
Por exemplo, para obter os produtos com preço superior a 50 e quantidade inferior a 30:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const docs = collection.find(
_mongo.filters().and(
_mongo.filters().gt("price", 50),
_mongo.filters().lt("quantity", 30)
)
).all()
const docs = collection.find(
_mongo.filters().and(
_mongo.filters().gt("price", 50),
_mongo.filters().lt("quantity", 30)
)
).all()
const docs = collection.find(
_mongo.filters().and(
_mongo.filters().gt("price", 50),
_mongo.filters().lt("quantity", 30)
)
).all()
const docs = collection.find(
_mongo.filters().and(
_mongo.filters().gt("price", 50),
_mongo.filters().lt("quantity", 30)
)
).all()
const docs = collection.find(
_mongo.filters().and(
_mongo.filters().gt("price", 50),
_mongo.filters().lt("quantity", 30)
)
).all()
Ou para obter os produtos cujo nome corresponde a uma expressão regular:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const docs = collection.find(
_mongo.filters().regex("name", "^[LS]")
).all()
const docs = collection.find(
_mongo.filters().regex("name", "^[LS]")
).all()
const docs = collection.find(
_mongo.filters().regex("name", "^[LS]")
).all()
const docs = collection.find(
_mongo.filters().regex("name", "^[LS]")
).all()
const docs = collection.find(
_mongo.filters().regex("name", "^[LS]")
).all()
Percorrer os Resultados
Com o resultado da consulta você pode percorrer todos os documentos encontrados:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
for (const doc of collection.find().all()) {
_out.println(doc.getString("name"))
}
for doc in collection.find().all():
_out.println(doc.getString("name"))
collection.find().all().each do |doc|
_out.println(doc.getString("name"))
end
for (doc in collection.find().all()) {
_out.println(doc.getString("name"))
}
for (doc in collection.find().all()) {
_out.println(doc.getString("name"))
}
Você também pode percorrer os resultados com forEach() passando uma função:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
collection.find().forEach((doc) =>
_out.println(doc.getString("name"))
)
collection.find().forEach((doc) =>
_out.println(doc.getString("name"))
)
collection.find().forEach((doc) =>
_out.println(doc.getString("name"))
)
collection.find().forEach((doc) =>
_out.println(doc.getString("name"))
)
collection.find().forEach((doc) =>
_out.println(doc.getString("name"))
)
Ordenação
Com a factory _mongo.sorts() você define a ordem dos resultados, de forma ascendente ou descendente:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const docs = collection.find().sort(
_mongo.sorts().descending("price")
).all()
const docs = collection.find().sort(
_mongo.sorts().descending("price")
).all()
const docs = collection.find().sort(
_mongo.sorts().descending("price")
).all()
const docs = collection.find().sort(
_mongo.sorts().descending("price")
).all()
const docs = collection.find().sort(
_mongo.sorts().descending("price")
).all()
Para ordenar por vários campos, utilize orderBy():
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const docs = collection.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("price"),
_mongo.sorts().ascending("quantity")
)
).all()
const docs = collection.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("price"),
_mongo.sorts().ascending("quantity")
)
).all()
const docs = collection.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("price"),
_mongo.sorts().ascending("quantity")
)
).all()
const docs = collection.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("price"),
_mongo.sorts().ascending("quantity")
)
).all()
const docs = collection.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("price"),
_mongo.sorts().ascending("quantity")
)
).all()
Projeção de Campos
Com a factory _mongo.projections() você limita os campos devolvidos nos documentos:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const docs = collection.find().projection(
_mongo.projections().include("name", "quantity")
).all()
const docs = collection.find().projection(
_mongo.projections().include("name", "quantity")
).all()
const docs = collection.find().projection(
_mongo.projections().include("name", "quantity")
).all()
const docs = collection.find().projection(
_mongo.projections().include("name", "quantity")
).all()
const docs = collection.find().projection(
_mongo.projections().include("name", "quantity")
).all()
Para combinar várias projeções:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const docs = collection.find().projection(
_mongo.projections().fields(
_mongo.projections().include("name", "quantity"),
_mongo.projections().excludeId()
)
).all()
const docs = collection.find().projection(
_mongo.projections().fields(
_mongo.projections().include("name", "quantity"),
_mongo.projections().excludeId()
)
).all()
const docs = collection.find().projection(
_mongo.projections().fields(
_mongo.projections().include("name", "quantity"),
_mongo.projections().excludeId()
)
).all()
const docs = collection.find().projection(
_mongo.projections().fields(
_mongo.projections().include("name", "quantity"),
_mongo.projections().excludeId()
)
).all()
const docs = collection.find().projection(
_mongo.projections().fields(
_mongo.projections().include("name", "quantity"),
_mongo.projections().excludeId()
)
).all()
Os tipos de projeção disponíveis são os seguintes:
| Projeção | Descrição |
|---|---|
include("campo", ...) | Inclui apenas os campos especificados. |
exclude("campo", ...) | Exclui os campos especificados. |
excludeId() | Exclui o campo _id. |
fields(projeção1, ...) | Combina projeções. |
slice("campo", n) | Inclui apenas os primeiros n elementos do campo de matriz. |
slice("campo", salto, n) | Inclui n elementos do campo de matriz, a partir de depois dos primeiros salto elementos. |
elemMatch("campo") | Inclui apenas o primeiro elemento do campo de matriz. |
elemMatch("campo", filtro) | Inclui apenas o primeiro elemento da matriz que corresponde ao filtro. |
computed("campo", expressão) | Adiciona um campo calculado com base numa expressão de agregação. |
Limites e Saltos
Com limit() e skip() você controla a quantidade de resultados devolvidos:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const docs = collection.find()
.skip(1)
.limit(2)
.all()
const docs = collection.find()
.skip(1)
.limit(2)
.all()
const docs = collection.find()
.skip(1)
.limit(2)
.all()
const docs = collection.find()
.skip(1)
.limit(2)
.all()
const docs = collection.find()
.skip(1)
.limit(2)
.all()
Atualizar Documentos
Com a factory _mongo.updates() você define as alterações a aplicar, e com updateOne() ou updateMany() aplica as alterações nos documentos que correspondem ao filtro:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
collection.updateOne(
_mongo.filters().eq("name", "Laptop"),
_mongo.updates().set("quantity", 42)
)
collection.updateMany(
_mongo.filters().eq("category", "computers"),
_mongo.updates().set("category", "featured")
)
collection.updateOne(
_mongo.filters().eq("name", "Laptop"),
_mongo.updates().set("quantity", 42)
)
collection.updateMany(
_mongo.filters().eq("category", "computers"),
_mongo.updates().set("category", "featured")
)
collection.updateOne(
_mongo.filters().eq("name", "Laptop"),
_mongo.updates().set("quantity", 42)
)
collection.updateMany(
_mongo.filters().eq("category", "computers"),
_mongo.updates().set("category", "featured")
)
collection.updateOne(
_mongo.filters().eq("name", "Laptop"),
_mongo.updates().set("quantity", 42)
)
collection.updateMany(
_mongo.filters().eq("category", "computers"),
_mongo.updates().set("category", "featured")
)
collection.updateOne(
_mongo.filters().eq("name", "Laptop"),
_mongo.updates().set("quantity", 42)
)
collection.updateMany(
_mongo.filters().eq("category", "computers"),
_mongo.updates().set("category", "featured")
)
A factory _mongo.updates() oferece os operadores de atualização:
| Operador | Descrição |
|---|---|
set("campo", valor) | Define o valor de um campo. |
unset("campo") | Remove um campo do documento. |
rename("campo", "novoNome") | Renomeia um campo. |
push("campo", valor) | Adiciona um valor a um array. |
combine(atualização1, atualização2, ...) | Combina várias atualizações numa só. |
Para aplicar várias alterações de uma só vez, utilize combine():
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const combined = _mongo.updates().combine(
_mongo.updates().set("quantity", 42),
_mongo.updates().rename("other", "more")
)
collection.updateOne(
_mongo.filters().eq("name", "Laptop"),
combined
)
const combined = _mongo.updates().combine(
_mongo.updates().set("quantity", 42),
_mongo.updates().rename("other", "more")
)
collection.updateOne(
_mongo.filters().eq("name", "Laptop"),
combined
)
const combined = _mongo.updates().combine(
_mongo.updates().set("quantity", 42),
_mongo.updates().rename("other", "more")
)
collection.updateOne(
_mongo.filters().eq("name", "Laptop"),
combined
)
const combined = _mongo.updates().combine(
_mongo.updates().set("quantity", 42),
_mongo.updates().rename("other", "more")
)
collection.updateOne(
_mongo.filters().eq("name", "Laptop"),
combined
)
const combined = _mongo.updates().combine(
_mongo.updates().set("quantity", 42),
_mongo.updates().rename("other", "more")
)
collection.updateOne(
_mongo.filters().eq("name", "Laptop"),
combined
)
Encontrar e atualizar
Com findOneAndUpdate() encontra e atualiza um documento de forma atómica, devolvendo o documento original (ou null se não houver nenhum):
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const old = collection.findOneAndUpdate(
_mongo.filters().eq("name", "Laptop"),
_mongo.updates().set("quantity", 42)
)
const old = collection.findOneAndUpdate(
_mongo.filters().eq("name", "Laptop"),
_mongo.updates().set("quantity", 42)
)
const old = collection.findOneAndUpdate(
_mongo.filters().eq("name", "Laptop"),
_mongo.updates().set("quantity", 42)
)
const old = collection.findOneAndUpdate(
_mongo.filters().eq("name", "Laptop"),
_mongo.updates().set("quantity", 42)
)
const old = collection.findOneAndUpdate(
_mongo.filters().eq("name", "Laptop"),
_mongo.updates().set("quantity", 42)
)
Substituir Documentos
Com replaceOne() substitui o documento inteiro (ao contrário das atualizações, não pode conter operadores de atualização):
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
collection.replaceOne(
_mongo.filters().eq("name", "Laptop"),
_val.map()
.set("name", "Laptop")
.set("quantity", 50)
.set("price", 150)
.set("category", "featured")
)
collection.replaceOne(
_mongo.filters().eq("name", "Laptop"),
_val.map()
.set("name", "Laptop")
.set("quantity", 50)
.set("price", 150)
.set("category", "featured")
)
collection.replaceOne(
_mongo.filters().eq("name", "Laptop"),
_val.map()
.set("name", "Laptop")
.set("quantity", 50)
.set("price", 150)
.set("category", "featured")
)
collection.replaceOne(
_mongo.filters().eq("name", "Laptop"),
_val.map()
.set("name", "Laptop")
.set("quantity", 50)
.set("price", 150)
.set("category", "featured")
)
collection.replaceOne(
_mongo.filters().eq("name", "Laptop"),
_val.map()
.set("name", "Laptop")
.set("quantity", 50)
.set("price", 150)
.set("category", "featured")
)
Para encontrar e substituir de forma atómica, devolvendo o documento antigo, utilize findOneAndReplace():
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const old = collection.findOneAndReplace(
_mongo.filters().eq("name", "Laptop"),
_val.map()
.set("name", "Laptop")
.set("quantity", 50)
)
const old = collection.findOneAndReplace(
_mongo.filters().eq("name", "Laptop"),
_val.map()
.set("name", "Laptop")
.set("quantity", 50)
)
const old = collection.findOneAndReplace(
_mongo.filters().eq("name", "Laptop"),
_val.map()
.set("name", "Laptop")
.set("quantity", 50)
)
const old = collection.findOneAndReplace(
_mongo.filters().eq("name", "Laptop"),
_val.map()
.set("name", "Laptop")
.set("quantity", 50)
)
const old = collection.findOneAndReplace(
_mongo.filters().eq("name", "Laptop"),
_val.map()
.set("name", "Laptop")
.set("quantity", 50)
)
Excluir Documentos
Com deleteOne() e deleteMany() exclui os documentos que correspondem ao filtro:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
collection.deleteOne(
_mongo.filters().eq("name", "Laptop")
)
collection.deleteMany(
_mongo.filters().eq("category", "inactive")
)
collection.deleteOne(
_mongo.filters().eq("name", "Laptop")
)
collection.deleteMany(
_mongo.filters().eq("category", "inactive")
)
collection.deleteOne(
_mongo.filters().eq("name", "Laptop")
)
collection.deleteMany(
_mongo.filters().eq("category", "inactive")
)
collection.deleteOne(
_mongo.filters().eq("name", "Laptop")
)
collection.deleteMany(
_mongo.filters().eq("category", "inactive")
)
collection.deleteOne(
_mongo.filters().eq("name", "Laptop")
)
collection.deleteMany(
_mongo.filters().eq("category", "inactive")
)
Para encontrar e excluir um documento de forma atómica, devolvendo o documento excluído, utilize findOneAndDelete():
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const old = collection.findOneAndDelete(
_mongo.filters().eq("name", "Tablet")
)
const old = collection.findOneAndDelete(
_mongo.filters().eq("name", "Tablet")
)
const old = collection.findOneAndDelete(
_mongo.filters().eq("name", "Tablet")
)
const old = collection.findOneAndDelete(
_mongo.filters().eq("name", "Tablet")
)
const old = collection.findOneAndDelete(
_mongo.filters().eq("name", "Tablet")
)
Para excluir todos os documentos da coleção, passe um filtro vazio com a ajuda de _mongo.valToDoc():
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
collection.deleteMany(_mongo.valToDoc(_val.map()))
collection.deleteMany(_mongo.valToDoc(_val.map()))
collection.deleteMany(_mongo.valToDoc(_val.map()))
collection.deleteMany(_mongo.valToDoc(_val.map()))
collection.deleteMany(_mongo.valToDoc(_val.map()))
Contar Documentos
Com countDocuments() obtém o número de documentos da coleção, opcionalmente com um filtro. Já estimatedDocumentCount() é mais rápido pois utiliza os metadados da coleção, mas sem filtro:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const total = collection.countDocuments()
const totalMain = collection.countDocuments(
_mongo.filters().eq("category", "computers")
)
const estimated = collection.estimatedDocumentCount()
const total = collection.countDocuments()
totalMain = collection.countDocuments(
_mongo.filters().eq("category", "computers")
)
estimated = collection.estimatedDocumentCount()
const total = collection.countDocuments()
totalMain = collection.countDocuments(
_mongo.filters().eq("category", "computers")
)
estimated = collection.estimatedDocumentCount()
const total = collection.countDocuments()
val totalMain = collection.countDocuments(
_mongo.filters().eq("category", "computers")
)
val estimated = collection.estimatedDocumentCount()
const total = collection.countDocuments()
final totalMain = collection.countDocuments(
_mongo.filters().eq("category", "computers")
)
final estimated = collection.estimatedDocumentCount()
Índices
Com a factory _mongo.indexes() cria índices para melhorar o desempenho das consultas. Para criar um índice basta passar as especificações ao createIndex():
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
collection.createIndex(
_mongo.indexes().ascending("quantity")
)
collection.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("price"),
_mongo.indexes().ascending("quantity")
)
)
collection.createIndex(
_mongo.indexes().ascending("quantity")
)
collection.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("price"),
_mongo.indexes().ascending("quantity")
)
)
collection.createIndex(
_mongo.indexes().ascending("quantity")
)
collection.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("price"),
_mongo.indexes().ascending("quantity")
)
)
collection.createIndex(
_mongo.indexes().ascending("quantity")
)
collection.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("price"),
_mongo.indexes().ascending("quantity")
)
)
collection.createIndex(
_mongo.indexes().ascending("quantity")
)
collection.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("price"),
_mongo.indexes().ascending("quantity")
)
)
Pode indicar ao MongoDB qual o índice a utilizar numa consulta, com o hint():
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const docs = collection.find().hint(
_mongo.valToDoc(
_val.map().set("quantity", 1)
)
).all()
const docs = collection.find().hint(
_mongo.valToDoc(
_val.map().set("quantity", 1)
)
).all()
const docs = collection.find().hint(
_mongo.valToDoc(
_val.map().set("quantity", 1)
)
).all()
const docs = collection.find().hint(
_mongo.valToDoc(
_val.map().set("quantity", 1)
)
).all()
const docs = collection.find().hint(
_mongo.valToDoc(
_val.map().set("quantity", 1)
)
).all()
Com min() e max() você limita a gama de valores do índice percorridos pela consulta:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const docs = collection.find()
.min(
_mongo.valToDoc(
_val.map().set("quantity", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("quantity", 50)
)
)
.all()
const docs = collection.find()
.min(
_mongo.valToDoc(
_val.map().set("quantity", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("quantity", 50)
)
)
.all()
const docs = collection.find()
.min(
_mongo.valToDoc(
_val.map().set("quantity", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("quantity", 50)
)
)
.all()
const docs = collection.find()
.min(
_mongo.valToDoc(
_val.map().set("quantity", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("quantity", 50)
)
)
.all()
const docs = collection.find()
.min(
_mongo.valToDoc(
_val.map().set("quantity", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("quantity", 50)
)
)
.all()
Agregações
Para análises mais avançadas, o aggregate() permite executar um pipeline de agregação, onde cada etapa é definida com a factory _mongo.aggregates() e os acumuladores com _mongo.accumulators().
Por exemplo, para agrupar os produtos pela categoria e somar o preço de cada grupo:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const docs = collection.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("category", "computers")
),
_mongo.aggregates().group(
"$category",
_mongo.accumulators().sum("total", "$price")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("total")
)
).all()
docs = collection.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("category", "computers")
),
_mongo.aggregates().group(
"$category",
_mongo.accumulators().sum("total", "$price")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("total")
)
).all()
docs = collection.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("category", "computers")
),
_mongo.aggregates().group(
"$category",
_mongo.accumulators().sum("total", "$price")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("total")
)
).all()
val docs = collection.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("category", "computers")
),
_mongo.aggregates().group(
"$category",
_mongo.accumulators().sum("total", "$price")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("total")
)
).all()
def docs = collection.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("category", "computers")
),
_mongo.aggregates().group(
"$category",
_mongo.accumulators().sum("total", "$price")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("total")
)
).all()
As etapas de agregação disponíveis são as seguintes:
| Etapa | Descrição |
|---|---|
match(filtro) | Seleciona apenas os documentos que correspondem ao filtro. |
group("$campo", acumuladores) | Agrupa os documentos pelo campo e aplica os acumuladores. |
project(projeção) | Adiciona, remove ou altera campos nos documentos. |
sort(ordenação) | Ordena os documentos. |
limit(n) | Limita aos primeiros n documentos. |
skip(n) | Salta os primeiros n documentos. |
count() | Conta o número de documentos. |
lookup("coleção", "campoLocal", "campoEstrangeiro", "como") | Executa um join com outra coleção. |
E os acumuladores mais utilizados:
| Acumulador | Descrição |
|---|---|
sum("campo", "$expressão") | Soma dos valores. |
avg("campo", "$expressão") | Média dos valores. |
min("campo", "$expressão") | Valor mínimo. |
max("campo", "$expressão") | Valor máximo. |
first("campo", "$expressão") | Valor do primeiro documento. |
last("campo", "$expressão") | Valor do último documento. |
top("campo", ordenação, "$expressão") | Valor do topo segundo a ordenação. |
bottom("campo", ordenação, "$expressão") | Valor de baixo segundo a ordenação. |
Nos acumuladores, a expressão com prefixo
$refere-se ao campo de um documento de entrada, por exemplo"$price".
Conversão entre Values e BSON
Por vezes é necessário converter entre os objetos _val do Netuno e documentos BSON do MongoDB:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const doc = _mongo.valToDoc(
_val.map().set("name", "Laptop")
)
const values = _mongo.docToVal(doc)
const doc = _mongo.valToDoc(
_val.map().set("name", "Laptop")
)
values = _mongo.docToVal(doc)
const doc = _mongo.valToDoc(
_val.map().set("name", "Laptop")
)
values = _mongo.docToVal(doc)
const doc = _mongo.valToDoc(
_val.map().set("name", "Laptop")
)
val values = _mongo.docToVal(doc)
const doc = _mongo.valToDoc(
_val.map().set("name", "Laptop")
)
final values = _mongo.docToVal(doc)
Operações com Opções
As factories *Options() do recurso _mongo devolvem os objetos de opções padrão do driver do MongoDB, e você pode encadear os seus métodos diretamente. Por exemplo, upsert(true) insere o documento quando o filtro não corresponde a nenhum documento existente:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
const old = collection.findOneAndUpdate(
_mongo.filters().eq("name", "Monitor"),
_mongo.updates().set("quantity", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
const old = collection.findOneAndUpdate(
_mongo.filters().eq("name", "Monitor"),
_mongo.updates().set("quantity", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
const old = collection.findOneAndUpdate(
_mongo.filters().eq("name", "Monitor"),
_mongo.updates().set("quantity", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
const old = collection.findOneAndUpdate(
_mongo.filters().eq("name", "Monitor"),
_mongo.updates().set("quantity", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
const old = collection.findOneAndUpdate(
_mongo.filters().eq("name", "Monitor"),
_mongo.updates().set("quantity", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
Quando o documento é inserido, o findOneAndUpdate() devolve null.
As factories de opções disponíveis são: insertOneOptions(), insertManyOptions(), updateOptions(), findOneAndUpdateOptions(), replaceOptions(), findOneAndReplaceOptions(), deleteOptions(), findOneAndDeleteOptions(), countOptions(), estimatedDocumentCountOptions(), dropCollectionOptions() e textSearchOptions().
Fechar a Conexão
Ao terminar, é uma boa prática fechar a conexão com o MongoDB:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
_mongo.close()
_mongo.close()
_mongo.close()
_mongo.close()
_mongo.close()
Conclusão
Com o recurso _mongo o Netuno oferece uma abstração low-code e poliglota sobre o cliente oficial do MongoDB para Java, permitindo trabalhar com documentos, filtros, ordenações, projeções, atualizações, índices e agregações em JavaScript, Python, Ruby, Kotlin e Groovy.
Para mais detalhes sobre todos os métodos disponíveis, consulte a documentação do recurso _mongo e da classe MongoCollection.
Bom desenvolvimento!