Explore Developer Center's New Chatbot! MongoDB AI Chatbot can be accessed at the top of your navigation to answer all your MongoDB questions.

Learn why MongoDB was selected as a leader in the 2024 Gartner® Magic Quadrant™
MongoDB Developer
Atlas
plus
Sign in to follow topics
MongoDB Developer Center
chevron-right
Developer Topics
chevron-right
Products
chevron-right
Atlas
chevron-right

Harnessing Natural Language for MongoDB Queries With Google Gemini

Venkatesh Shanbhag, Yemi Falokun8 min read • Published Dec 13, 2024 • Updated Dec 13, 2024
AIGoogle CloudAtlasPython
Facebook Icontwitter iconlinkedin icon
Rate this article
star-empty
star-empty
star-empty
star-empty
star-empty
In the digital age, leveraging natural language for database queries represents a leap toward more intuitive data management. Vertex AI Extensions, currently in public preview, help in interacting with MongoDB using natural language. This tutorial introduces an approach that combines Google Gemini's advanced natural language processing with MongoDB, facilitated by Vertex AI Extensions.
These extensions address key limitations of large language models (LLMs) by enabling real-time data querying and modification, which LLMs cannot do due to their static knowledge base post-training. By integrating MongoDB Atlas with Vertex AI Extensions, we offer a solution that reduces hallucination and ensures that the responses are grounded in the enterprise information stored in Atlas DB.
MongoDB's dynamic schema, scalability, and comprehensive querying capabilities render it exemplary for Generative AI applications. It is adept at handling the versatile and unpredictable nature of data that these applications generate and use. From personalized content generation, where user data shapes content in real time, to sophisticated, AI-driven recommendation systems leveraging up-to-the-minute data for tailored suggestions, MongoDB stands out. Furthermore, it excels in complex data analysis, allowing AI tools to interact with vast and varied datasets to extract meaningful insights, showcasing its pivotal role in enhancing the efficiency and effectiveness of Generative AI applications.

Natural language to MongoDB queries

Natural language querying represents a paradigm shift in data interaction, allowing users to retrieve information without the need for custom query languages. By integrating MongoDB with a system capable of understanding and processing natural language, we streamline database operations, making them more accessible to non-technical users.

Solution blueprint

The solution involves a synergy of several components, including MongoDB, the Google Vertex AI SDK, Google Secrets Manager, and OpenAPI 3 specifications. Together, these elements create a robust framework that translates natural language queries into MongoDB Data API calls. In this solution, we have explored basic CRUD operations with Vertex AI Extensions. We are closely working with Google to enable vector search aggregations in the near future.

Components involved

  1. MongoDB: A versatile, document-oriented database that stores data in JSON-like formats, making it highly adaptable to various data types and structures
  2. Google Vertex AI SDK: Facilitates the creation and management of AI and machine learning models, including the custom extension for Google Vertex AI
  3. Vertex AI Extensions: Enhance LLMs by allowing them to interact with external systems in real-time, extending their capabilities beyond static knowledge
  4. Google Secrets Manager: Securely stores sensitive information, such as MongoDB API keys, ensuring the solution's security and integrity
  5. OpenAPI 3 Specification for MongoDB Data API: Defines a standard, language-agnostic interface to MongoDB that allows for both easy integration and clear documentation of the API's capabilities

Description of the solution

The solution operates by converting natural language queries into parameters that the MongoDB API can understand. This conversion is facilitated by a custom extension developed using the Google Vertex AI extension SDK, which is then integrated with Gemini 1.5 Pro. The extension leverages OpenAPI 3 specifications to interact with MongoDB, retrieving data based on the user's natural language input. Google Secrets Manager plays a critical role in securely managing API keys required for MongoDB access, ensuring the solution's security.
architecture diagram of the Vertex AI extensions

Prerequisites

Before you start, make sure you have the following:
  1. Secure your access to the Google Cloud project or to create a new project.
  2. If you are new to MongoDB Atlas, you can sign up to MongoDB either through the Google Cloud Marketplace or with the Atlas registration page.
  3. Vertex AI Extensions are not publicly available. Please sign up for the Extensions Trusted Tester Program.
  4. Basic knowledge of OpenAPI specifications and how to create them for APIs will be helpful.
  5. You’ll need a Google Cloud Storage bucket for storing the OpenAPI specifications.
Before we begin, also make sure you:
Create a Google Cloud Run Function to call MongoDB Atlas using python drivers. To Create a function Open Google Cloud Run Function and click on create function.
  • Provide a function Name and select a region.
  • Allow Unauthenticated access, leave the other options to default and click on next.
  • Select Python as a Runtime (Select the latest version available).
  • Copy the below code and paste in main.py.
1import functions_framework
2import os
3import json
4from pymongo import MongoClient
5from bson import ObjectId
6import traceback
7from datetime import datetime
8
9
10def connect_to_mongodb():
11 client = MongoClient("<MongoDB Connection String>")
12 return client
13
14
15def success_response(body):
16 return {
17 'statusCode': '200',
18 'body': json.dumps(body, cls=DateTimeEncoder),
19 'headers': {
20 'Content-Type': 'application/json',
21 },
22 }
23
24
25def error_response(err):
26 error_message = str(err)
27 return {
28 'statusCode': '400',
29 'body': error_message,
30 'headers': {
31 'Content-Type': 'application/json',
32 },
33 }
34
35
36# Used to convert datetime object(s) to string
37class DateTimeEncoder(json.JSONEncoder):
38 def default(self, o):
39 if isinstance(o, datetime):
40 return o.isoformat()
41 return super().default(o)
42
43
44@functions_framework.http
45def mongodb_crud(request):
46 client = connect_to_mongodb()
47 payload = request.get_json(silent=True)
48 db, coll = payload['database'], payload['collection']
49 request_args = request.args
50 op = request.path
51 try:
52 if op == "/findOne":
53 filter_op = payload['filter'] if 'filter' in payload else {}
54 projection = payload['projection'] if 'projection' in payload else {}
55 result = {"document": client[db][coll].find_one(filter_op, projection)}
56 if result['document'] is not None:
57 if isinstance(result['document']['_id'], ObjectId):
58 result['document']['_id'] = str(result['document']['_id'])
59
60 elif op == "/find":
61 agg_query = []
62
63 if 'filter' in payload and payload['filter'] != {}:
64 agg_query.append({"$match": payload['filter']})
65
66 if "sort" in payload and payload['sort'] != {}:
67 agg_query.append({"$sort": payload['sort']})
68
69 if "skip" in payload:
70 agg_query.append({"$skip": payload['skip']})
71
72 if 'limit' in payload:
73 agg_query.append({"$limit": payload['limit']})
74
75 if "projection" in payload and payload['projection'] != {}:
76 agg_query.append({"$project": payload['projection']})
77
78 result = {"documents": list(client[db][coll].aggregate(agg_query))}
79 for obj in result['documents']:
80 if isinstance(obj['_id'], ObjectId):
81 obj['_id'] = str(obj['_id'])
82
83 elif op == "/insertOne":
84 if "document" not in payload or payload['document'] == {}:
85 return error_response("Send a document to insert")
86 insert_op = client[db][coll].insert_one(payload['document'])
87 result = {"insertedId": str(insert_op.inserted_id)}
88
89 elif op == "/insertMany":
90 if "documents" not in payload or payload['documents'] == {}:
91 return error_response("Send a document to insert")
92 insert_op = client[db][coll].insert_many(payload['documents'])
93 result = {"insertedIds": [str(_id) for _id in insert_op.inserted_ids]}
94
95 elif op in ["/updateOne", "/updateMany"]:
96 payload['upsert'] = payload['upsert'] if 'upsert' in payload else False
97 if "_id" in payload['filter']:
98 payload['filter']['_id'] = ObjectId(payload['filter']['_id'])
99 if op == "/updateOne":
100 update_op = client[db][coll].update_one(payload['filter'], payload['update'], upsert=payload['upsert'])
101 else:
102 update_op = client[db][coll].update_many(payload['filter'], payload['update'], upsert=payload['upsert'])
103 result = {"matchedCount": update_op.matched_count, "modifiedCount": update_op.modified_count}
104
105 elif op in ["/deleteOne", "/deleteMany"]:
106 payload['filter'] = payload['filter'] if 'filter' in payload else {}
107 if "_id" in payload['filter']:
108 payload['filter']['_id'] = ObjectId(payload['filter']['_id'])
109 if op == "/deleteOne":
110 result = {"deletedCount": client[db][coll].delete_one(payload['filter']).deleted_count}
111 else:
112 result = {"deletedCount": client[db][coll].delete_many(payload['filter']).deleted_count}
113
114 elif op == "/aggregate":
115 if "pipeline" not in payload or payload['pipeline'] == []:
116 return error_response("Send a pipeline")
117 docs = list(client[db][coll].aggregate(payload['pipeline']))
118 for obj in docs:
119 if isinstance(obj['_id'], ObjectId):
120 obj['_id'] = str(obj['_id'])
121 result = {"documents": docs}
122
123 else:
124 return error_response("Not a valid operation")
125
126 return success_response(result)
127
128 except Exception as e:
129 print(traceback.format_exc())
130 return error_response(e)
131
132 finally:
133 if client:
134 client.close()
  • Copy the required requirements as well to requirements.py file.
1functions-framework==3.*
2pymongo
3pymongo[srv]
  • Rename the Entry Point as "mongodb_crud" and deploy the function.
  • Copy and store locally the Https Endpoint(URL) for triggering the Cloud Function.
  • Navigate to the details page of the Cloud function and copy and store the service account name used by the function.
Note: detailed code and steps to setup is available in the Github Repository.

Create Vertex AI extensions

This tutorial uses the MongoDB default dataset from the sample_mflix database, movies collection. We will run all the below code on the Enterprise Colab notebook.
  1. Vertex AI Extensions is a platform for creating and managing extensions that connect large language models to external systems via APIs. These external systems can provide LLMs with real-time data and perform data processing actions on their behalf.
1from google.colab import auth
2auth.authenticate_user("GCP project id")
3!gcloud config set project {"GCP project id"}
  1. Install the required Python dependencies.
1!pip install --force-reinstall --quiet google_cloud_aiplatform
2# This is for printing the Vertex AI service account.
3!pip install --force-reinstall --quiet langchain==0.0.298
4
5!pip install --upgrade google-auth
6!pip install bigframes==0.26.0
  1. Once the dependencies are installed, restart the kernel.
1import IPython
2app = IPython.Application.instance()
3app.kernel.do_shutdown(True) # Re-run the Env variable cell again after Kernel restart
  1. Initialize the environment variables.
1import os
2## This is just a sample values please replace accordingly to your project
3# Setting up the GCP project
4os.environ['PROJECT_ID'] = 'gcp project id' # GCP Project ID
5os.environ['REGION'] = "us-central1" # Project Region
6## GCS Bucket location
7os.environ['STAGING_BUCKET'] = "gs://vertexai_extensions"
8## Extension Config
9os.environ['EXTENSION_DISPLAY_HOME'] = "MongoDb Vertex API Interpreter"
10os.environ['EXTENSION_DESCRIPTION'] = "This extension makes api call to mongodb to do all crud operations"
11
12
13## OPEN API SPec config
14os.environ['MANIFEST_NAME'] = "mdb_crud_interpreter"
15os.environ['MANIFEST_DESCRIPTION'] = "This extension makes api call to mongodb to do all crud operations"
16os.environ['OPENAPI_GCS_URI'] = "gs://vertexai_extensions/mongodbopenapispec.yaml"
17
18
19## API KEY secret location
20os.environ['API_SECRET_LOCATION'] = "projects/787220387490/secrets/mdbapikey/versions/1"
21
22
23##LLM config
24os.environ['LLM_MODEL'] = "gemini-1.5-pro"
  1. Download the Open API specification from GitHub and upload the YAML file to the Google Cloud Storage bucket.
1from google.cloud import aiplatformfrom google.cloud.aiplatform.private_preview import llm_extension
2
3PROJECT_ID = os.environ['PROJECT_ID']
4REGION = os.environ['REGION']
5STAGING_BUCKET = os.environ['STAGING_BUCKET']
6
7aiplatform.init(
8 project=PROJECT_ID,
9 location=REGION,
10 staging_bucket=STAGING_BUCKET,
11)
  1. To create the Vertex AI extension, run the below script. The manifest here is a structured JSON object containing several key components:
1from google.cloud import aiplatform
2from vertexai.preview import extensions
3
4mdb_crud = extensions.Extension.create(
5 display_name = EXTENSION_DISPLAY_HOME,
6 # Optional.
7 description = EXTENSION_DESCRIPTION,
8 manifest = {
9 "name": MANIFEST_NAME,
10 "description": MANIFEST_DESCRIPTION,
11 "api_spec": {
12 "open_api_gcs_uri": (
13 OPENAPI_GCS_URI
14 ),
15 },
16 "authConfig": {
17 "authType": "OAUTH",
18 "oauthConfig": {"service_account": "<Service account name here>"}
19 },
20 },
21 )
22mdb_crud
  1. Validate the Created Extension, and print the Operation Schema and Parameters.
1print("Name:", mdb_crud.gca_resource.name)print("Display Name:", mdb_crud.gca_resource.display_name)print("Description:", mdb_crud.gca_resource.description)
2import pprint
3pprint.pprint(mdb_crud.operation_schemas())

Extension in action

Once the extension is created, navigate to Vertex AI UI and then Vertex UI Extension on the left pane.
Navigating to Vertex AI extensions
All the created extensions will be available for selection. Select MongoDB Vertex API Interpreter. For this tutorial, we will consider two user journeys.

User Journey 1

Retrieve data through Vertex AI extensions: Imagine needing to quickly find out when a classic film was released without navigating through the database manually. By asking Vertex AI, "Find the release year of the movie 'A Corner in Wheat' from VertexAI-POC cluster, sample_mflix, movies," you get the specific release year, as the system performs a findOne() operation to retrieve this detail.
Testing Vertex AI extensions for find query
In addition to using the UI, we can also use the Notebook to query MongoDB using natural language processing. We are using Gemini to convert natural language to the actual operation schema for calling the Vertex AI extension. Update the environment variable and run the below script.
1## Please replace accordingly to your project
2## Operation Ids
3os.environ['FIND_ONE_OP_ID'] = "findone_mdb"
4
5
6
7
8## NL Queries
9os.environ['FIND_ONE_NL_QUERY'] = "Find the release year of the movie 'A Corner in Wheat' from VertexAI-POC cluster, sample_mflix, movies"
10
11
12## Mongodb Config
13os.environ['DATA_SOURCE'] = "VertexAI-POC"
14os.environ['DB_NAME'] = "sample_mflix"
15os.environ['COLLECTION_NAME'] = "movies"
16
17
18### Test data setup
19os.environ['TITLE_FILTER_CLAUSE'] = "A Corner in Wheat"
20
21from vertexai.preview.generative_models import GenerativeModel, Tool
22
23fc_chat = GenerativeModel(os.environ['LLM_MODEL']).start_chat()
24findOneResponse = fc_chat.send_message(os.environ['FIND_ONE_NL_QUERY'],
25 tools=[Tool.from_dict({ "function_declarations": mdb_crud.operation_schemas()
26 })],
27)
28
29findOneResponse
From the converted schema, query the extension.
1response = mdb_crud.execute(
2 operation_id = findOneResponse.candidates[0].content.parts[0].function_call.name,
3 operation_params = findOneResponse.candidates[0].content.parts[0].function_call.args
4)
5
6response

User Journey 2

Retrieve data through Vertex AI extensions: A film historian wants a list of all movies released in a specific year — say 1924 — to study the cinematic trends of that era. They could ask, "Give me movies released in the year 1924 from VertexAI-POC cluster, sample_mflix, movies," and the system would use the find() method to list all movies from 1924, providing a comprehensive snapshot of that year's cinematic output.
testing Vertex AI extensions for find query 2
In addition to using the UI, we can also use the Notebook to query MongoDB using natural language processing.
Here’s the Gemini integration for natural language to extension schema conversion:
1## This is just a sample values please replace accordingly to your project
2## Operation Ids
3os.environ['FIND_MANY_OP_ID'] = "findmany_mdb"
4
5
6## NL Queries
7os.environ['FIND_MANY_NL_QUERY'] = "give me movies released in year 1924 from VertexAI-POC cluster, sample_mflix, movies"
8
9
10
11
12## Mongodb Config
13os.environ['DATA_SOURCE'] = "VertexAI-POC"
14os.environ['DB_NAME'] = "sample_mflix"
15os.environ['COLLECTION_NAME'] = "movies"
16os.environ['YEAR'] = 1924
17fc_chat = GenerativeModel(os.environ['LLM_MODEL']).start_chat()
18findmanyResponse = fc_chat.send_message(os.environ['FIND_MANY_NL_QUERY'],
19 tools=[Tool.from_dict({ "function_declarations": mdb_crud.operation_schemas()
20 })],
21)
22
23findmanyResponse
Execute the extension to get the response.
1response = mdb_crud.execute(
2 operation_id = findmanyResponse.candidates[0].content.parts[0].function_call.name,
3 operation_params = findmanyResponse.candidates[0].content.parts[0].function_call.args
4)
5
6response

Step by step extension execution

User queries with natural language
LLM converts natural language accordingly to extension schema and executes extension
Extension fetches the document from MongoDB and returns the response
LLM converts the extension response to natural language and responds back to user

Conclusion

In conclusion, integrating MongoDB with natural language querying capabilities revolutionizes data interaction, enhancing accessibility and intuitiveness for database queries. Leveraging the Google Gemini Foundation Model alongside a custom Vertex AI extension not only enriches the data retrieval experience but also upholds data security and integrity. We are closely working with the Google Cloud team to add even more query patterns to Vertex AI extensions. Watch out for more in this space.

Further reading

  1. Get started with MongoDB Atlas on Google Cloud.
  2. Connect models to APIs by using Vertex AI extensions.
Top Comments in Forums
There are no comments on this article yet.
Start the Conversation

Facebook Icontwitter iconlinkedin icon
Rate this article
star-empty
star-empty
star-empty
star-empty
star-empty
Related
Tutorial

Exploring Window Operators in Atlas Stream Processing


Aug 13, 2024 | 4 min read
Tutorial

Build an Image Search Engine With Python & MongoDB


Sep 18, 2024 | 8 min read
Tutorial

MongoDB Atlas With Terraform - Cluster and Backup Policies


Sep 11, 2024 | 22 min read
Tutorial

Integrate Atlas Application Services Logs Into Datadog on AWS


Sep 09, 2024 | 2 min read
Table of Contents