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 .

Learn why MongoDB was selected as a leader in the 2024 Gartner® Magic Quadrant™
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Produtoschevron-right
MongoDBchevron-right

Gerando comandos de shell MQL usando OpenAI e o novo shell mongosh

Pavel Duchovny7 min read • Published Jul 23, 2021 • Updated Jul 11, 2023
IAMongoDBShell
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Artigo
star-empty
star-empty
star-empty
star-empty
star-empty

Gerando comandos de shell MQL usando OpenAI e o novo shell mongosh

OpenAI é uma plataforma de AI fascturante e em crescimento hospedada pela Microsoft, permitindo a você digerir texto de forma habilidosa para produzir conteúdo de AI com resultados surpreendentes, considerando o tamanho do "learning data set " que você realmente fornece.
A Query Language (MQL) do MongoDB é uma linguagem intuitiva para os desenvolvedores interagirem com documentos do MongoDB. Por esse motivo, eu queria colocar a OpenAI no teste de aprender rapidamente a linguagem MongoDB e usar seu conhecimento geral para construir queries a partir de frases simples. Os resultados foram mais do que satisfeitos para me. O Github já está trabalhando em um projeto chamado Github copilot que usa o mesmo mecanismo OpenAI para codificar.
Neste artigo, mostrarei meu experimento, incluindo os recursos de mudança de jogo do novo MongoDB Shell (mongosh), que pode estender a script com integrações de módulos npm.

O que é OpenAI e como faço para obter acesso a ele?

OpenAI é um projeto único com o objetivo de fornecer uma API para muitas tarefas de AI construídas principalmente no Processamento de Linguagem Natural atualmente. Você pode ler mais sobre seus projetos neste blog.
Há uma variedade de exemplos de seus recursos de processamento de texto.
Se você quiser usar o OpenAI, precisará obter uma chave de API de teste primeiro, juntando-se à lista deespera na páginaprincipal. Depois de ser aprovado para obter uma chave de API, você receberá cerca de US$18 por três meses de testes. Cada chamada no OpenAI é cobrada e isso é algo a considerar ao usar em produção. Para nossos fins, US$18 é mais que suficiente para testar o mecanismo mais caro chamado “davinci.”
Depois de obter a API key, você pode usar vários clientes para executar a AI API a partir do seu script/aplicativo.
Como usaremos o novo shellmongosh, usei a API JS.

Preparando o mongosh para usar o OpenAI

Primeiro, precisamos instalar o novo shell, caso não o tenha feito até agora. No meu laptop Mac, acabou de emitir:
1brew install mongosh
Os usuários do Windows devem baixar o instalador MSI de nossa página de download e seguir as instruções do Windows.
Quando meu mongosh estiver pronto, posso começar a usá-lo, mas antes de fazer isso, vamos instalar o OpenAI JS, que importaremos no shell mais tarde:
1$ mkdir openai-test
2$ cd openai-test
3Openai-test $ npm i openai-api
Decidi usar o padrão Perguntas e Respostas, na forma de Q: <Question> e A: <Answer>, fornecido ao texto para APIde comandopara fornecer o material de aprendizado sobre MongoDB para o AI. Para melhor atualizá-lo, coloque as perguntas e respostas do treinamento em um arquivo chamado AI-input.txt e seu conteúdo:
1Q: What is the query syntax?
2A: db.collection.find(<filter>, <projection> , <options>)
3Q: Query users collection for username with value "boy"
4A: db.users.find({"username" : "boy"})
5Q: Query users collection for username with value "girl"A: db.users.find({"username" : "girl"})
6Q: Query users collection for username with age bigger than 16
7A: db.users.find({"age" : {$gt : 16}})n;
8Q: Query author collection for username with value "boy"
9A: db.authors.find({"username" : "boy"})
10Q:Query author collection for age lower than 7
11A: db.authors.find({"age" : {$lt : 7}});
12
13Q:insert a json document into collection authors with username equal to "girl"
14A: db.authors.insert({"username" : "girl"}, {"age" : 10, "gender" : "female"})
15Q: insert many documents into users collections
16A: db.users.insertMany([{username : "john doe"}, {username : "joe doe"}]);
17Q: The following aggregation uses $geoNear to find documents with a location at most 2 meters from the center [ -73.99279 , 40.719296 ] and a category equal to Parks.
18A: db.places.aggregate([{ $geoNear: {near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] },distanceField: "dist.calculated",maxDistance: 2, query: { category: "Parks" },includeLocs: "dist.location", spherical: true}}])
19Q: How to build atlas $search text query?
20A: db.collection.aggregate({$search: {"index": <index name> "text": {"query": "<search-string>","path": "<field-to-search>", "fuzzy": <options>,"score": <options> } }})
21
22Q: What is the aggregate syntax?
23A: db.collection.aggregate([<stage1>,<stage2>,<stage3>], <projection> , <options>);
24Q: aggregate users collection to calculate salary sum per user
25A: db.users.aggregate([{$group : { _id : "$username" , salary_sum : { $sum : "$salary" }}}]);
26Q: aggregate person collection to calculate salary sum per person
27A: db.persons.aggregate([{$group : { _id : "$person" , salary_sum : { $sum : "$salary" }}}]);
28Q: Lookup users and orders collection
29A: db.users.aggregate([{$lookup : {from: 'orders', localField : "_id", foreignField : "userId", as : "result" }} ]);
30
31Q: What is the update syntax?
32A:db.collection.update(query, update, options)
33Q: How to edit collection sports where sportname is 'football' and match is 'england vs portugal' to score of '3-3' and date to current date?
34A: db.sports.update({ sportname: "football", match: "england vs portugal"} , {$set : {score: "3-3" , date : new Date()}} })
35Q: Query and atomically update collection zoo where animal is "bear" with a counter increment on eat field, if the data does not exist user upsert
36A: db.zoo.findOneAndUpdate({animal : "bear"}, {$inc: { eat : 1 }} , {upsert : true})
Usaremos este arquivo mais tarde em nosso código.
Dessa forma, a conclusão será baseada em um padrão semelhante.

Prepare seu cluster do Atlas

O MongoDB Atlas, o serviço de banco de dados como plataforma, é uma ótima maneira de ter um cluster em execução em segundos com um conjunto de dados de amostra já lá para nosso teste. Para prepará-lo, use as seguintes etapas:
  1. Crie uma conta Atlas (se ainda não tiver uma) e use/inicie um cluster. Para obter etapas detalhadas, siga esta documentação.
Use a connection string copiada, fornecendo-a ao bináriomongosh para se conectar ao Atlas cluster pré-preenchido com dados de amostra. Em seguida, mude para o banco de dados dosample_restaurants.
1mongosh "mongodb+srv://<u>:<p>@<atlas-uri>/sample_restaurants"
2Using Mongosh : X.X.X
3Using MongoDB: X.X.X
4
5For mongosh info see: https://docs.mongodb.com/mongodb-shell/
6
7ATLAS atlas-ugld61-shard-0 [primary]> use sample_restaurants;

Usando OpenAI Dentro do shell mongosh

Agora, podemos construir nossa funçãotextToMql colando-a no mongosh. A função receberá uma frase de texto, usará nossa chave API OpenAI gerada e tentará retornar o melhor comando MQL para ela:
1async function textToMql(query){
2
3const OpenAI = require('openai-api');
4const openai-client = new OpenAI("<YOUR-OPENAI-API-KEY>");
5
6const fs = require('fs');
7
8var data = await fs.promises.readFile('AI-input.txt', 'utf8');
9
10const learningPath = data;
11
12var aiInput = learningPath + "Q:" + query + "\nA:";
13
14 const gptResponse = await openai-client.complete({
15 engine: 'davinci',
16 prompt: aiInput,
17 "temperature": 0.3,
18 "max_tokens": 400,
19 "top_p": 1,
20 "frequency_penalty": 0.2,
21 "presence_penalty": 0,
22 "stop": ["\n"]
23 });
24
25 console.log(gptResponse.data.choices[0].text);
26}
Na função acima, primeiro carregamos o módulo npm do OpenAI e iniciamos um cliente com a chave de API relevante do OpenAI.
1const OpenAI = require('openai-api');
2const openai-client = new OpenAI("<YOUR-OPENAI-API-KEY>");
3
4const fs = require('fs');
O novo shell nos permite importar módulosintegrados e externos para produzir uma flexibilidade ilimitada com nossos scripts.
Em seguida, lemos os dados de aprendizado do nosso arquivoAI-input.txt. Por fim, adicionamos nossa entradaQ: <query> ao final, seguida pelo valorA: , que informa ao mecanismo que esperamos uma resposta com base no learningPath fornecido e em nossa consulta.
Esses dados irão Go para uma chamada de API OpenAI:
1 const gptResponse = await openai.complete({
2 engine: 'davinci',
3 prompt: aiInput,
4 "temperature": 0.3,
5 "max_tokens": 400,
6 "top_p": 1,
7 "frequency_penalty": 0.2,
8 "presence_penalty": 0,
9 "stop": ["\n"]
10 });
A chamada executa uma API de conclusão e obtém todo o texto inicial como prompt e recebe alguns parâmetros adicionais, que detalharei:
  • engine: O OpenAI suporta alguns mecanismos de AI que diferem em qualidade e finalidade em troca de preços. O motor "davinci" é o mais sofisticado, de acordo com a OpenAI, e, portanto, é o mais caro em termos de consumo de faturamento.
  • temperature: quão criadora será o AI em comparação com as informações que demos a ele? Pode ser entre 0e1. 0.3 parece um valor simples, mas você pode jogar com ele.
  • Max_tokens: descreve a quantidade de dados que serão retornados.
  • Stop: Lista de personagens que impedirão o motor de produzir mais conteúdo. Como precisamos produzir declarações MQL, ela será baseada em uma linha e "\n " será um caractere de parada.
Depois que o conteúdo for retornado, analisamos o JSON retornado e o imprimimos com console.log.

Vamos colocar a OpenAI à prova com o MQL

Assim que tivermos nossa função em vigor, podemos tentar produzir uma consulta simples para testá-la:
1Atlas atlas-ugld61-shard-0 [primary] sample_restaurants> textToMql("query all restaurants where cuisine is American and name starts with 'Ri'")
2 db.restaurants.find({cuisine : "American", name : /^Ri/})
3
4Atlas atlas-ugld61-shard-0 [primary] sample_restaurants> db.restaurants.find({cuisine : "American", name : /^Ri/})
5[
6 {
7 _id: ObjectId("5eb3d668b31de5d588f4292a"),
8 address: {
9 building: '2780',
10 coord: [ -73.98241999999999, 40.579505 ],
11 street: 'Stillwell Avenue',
12 zipcode: '11224'
13 },
14 borough: 'Brooklyn',
15 cuisine: 'American',
16 grades: [
17 {
18 date: ISODate("2014-06-10T00:00:00.000Z"),
19 grade: 'A',
20 score: 5
21 },
22 {
23 date: ISODate("2013-06-05T00:00:00.000Z"),
24 grade: 'A',
25 score: 7
26 },
27 {
28 date: ISODate("2012-04-13T00:00:00.000Z"),
29 grade: 'A',
30 score: 12
31 },
32 {
33 date: ISODate("2011-10-12T00:00:00.000Z"),
34 grade: 'A',
35 score: 12
36 }
37 ],
38 name: 'Riviera Caterer',
39 restaurant_id: '40356018'
40 }
41...
Que legal! Nunca ensinamos ao mecanismo sobre a collectionrestaurants ou como filtrar com operadoresregex, mas ele ainda tomava as decisões corretas de AI.
Vamos fazer algo mais Criativo.
1Atlas atlas-ugld61-shard-0 [primary] sample_restaurants> textToMql("Generate an insert many command with random fruit names and their weight")
2 db.fruits.insertMany([{name: "apple", weight: 10}, {name: "banana", weight: 5}, {name: "grapes", weight: 15}])
3Atlas atlas-ugld61-shard-0 [primary]sample_restaurants> db.fruits.insertMany([{name: "apple", weight: 10}, {name: "banana", weight: 5}, {name: "grapes", weight: 15}])
4{
5 acknowledged: true,
6 insertedIds: {
7 '0': ObjectId("60e55621dc4197f07a26f5e1"),
8 '1': ObjectId("60e55621dc4197f07a26f5e2"),
9 '2': ObjectId("60e55621dc4197f07a26f5e3")
10 }
11}
Ok, agora vamos colocar isso no teste final: agregações!
1Atlas atlas-ugld61-shard-0 [primary] sample_restaurants> use sample_mflix;
2Atlas atlas-ugld61-shard-0 [primary] sample_mflix> textToMql("Aggregate the count of movies per year (sum : 1) on collection movies")
3 db.movies.aggregate([{$group : { _id : "$year", count : { $sum : 1 }}}]);
4
5Atlas atlas-ugld61-shard-0 [primary] sample_mflix> db.movies.aggregate([{$group : { _id : "$year", count : { $sum : 1 }}}]);
6[
7 { _id: 1967, count: 107 },
8 { _id: 1986, count: 206 },
9 { _id: '2006è2012', count: 2 },
10 { _id: 2004, count: 741 },
11 { _id: 1918, count: 1 },
12 { _id: 1991, count: 252 },
13 { _id: 1968, count: 112 },
14 { _id: 1990, count: 244 },
15 { _id: 1933, count: 27 },
16 { _id: 1997, count: 458 },
17 { _id: 1957, count: 89 },
18 { _id: 1931, count: 24 },
19 { _id: 1925, count: 13 },
20 { _id: 1948, count: 70 },
21 { _id: 1922, count: 7 },
22 { _id: '2005è', count: 2 },
23 { _id: 1975, count: 112 },
24 { _id: 1999, count: 542 },
25 { _id: 2002, count: 655 },
26 { _id: 2015, count: 484 }
27]
Esse éo poder de AI dos pipelines MongoDB !

Demonstração

asciicast

Resumo

O novo shell do MongoDB nos permite criar scripts com um poder enorme como nunca antes, utilizando pacotes externos npm. Junto com o poder dos sofisticados padrões de AI do OpenAI, pudemos ensinar o shell a solicitar texto a comandos complexos e precisos do MongoDB e, com mais aprendizado e ajustes, provavelmente poderemos obter resultados muito melhores.
Experimente isso hoje mesmo usando o novo shell MongoDB.

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Artigo
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Notícias e anúncios

MongoDB 3.6: Aqui para o SRV com conexões de conjunto de réplicas mais fáceis


Sep 23, 2022 | 4 min read
Tutorial

Otimizando o desempenho de $lookup usando o poder da indexação


Aug 30, 2024 | 7 min read
Artigo

Queries que não diferenciam maiúsculas de minúsculas sem índices que não diferenciam maiúsculas de minúsculas


Oct 01, 2024 | 8 min read
Tutorial

Explorando os recursos avançados do Atlas Search com o MongoDB Atlas Atlas Search


Aug 20, 2024 | 6 min read
Sumário
  • Gerando comandos de shell MQL usando OpenAI e o novo shell mongosh