Read and Write MongoDB
This example uses the off-the-shelf flink-sql-connector-mongodb connector for
Flink to write rows to a MongoDB collection and read them back. The connector is a
released JAR from Maven Central and needs no custom code, so it is a good model
for adding any third-party Flink SQL connector. For the artifact mechanism, see
Custom Connectors and Formats in Confluent Manager for Apache Flink.
Prerequisites
Complete the examples setup first. It provides the
test environment, the pool compute pool, and artifact management. This
example also needs:
A MongoDB instance reachable from the Flink cluster (installed below).
The
flink-sql-connector-mongodbJAR that matches the Flink cluster version, for exampleflink-sql-connector-mongodb-2.0.0-1.19.jarfrom Maven Central.
Install MongoDB
For a self-contained demo, run a single mongo:7 instance in the cluster. This
manifest, mongodb.yaml, creates the deployment and a mongo-service the Flink
cluster reaches by its in-cluster DNS name. It has no persistence, so it is for
demos only. Substitute your own MongoDB for anything you want to keep.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo-test
namespace: flink
spec:
replicas: 1
selector:
matchLabels:
app: mongo-test
template:
metadata:
labels:
app: mongo-test
spec:
containers:
- name: mongo
image: mongo:7
ports:
- containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
value: admin
- name: MONGO_INITDB_ROOT_PASSWORD
value: mongo-pass
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
name: mongo-service
namespace: flink
spec:
selector:
app: mongo-test
ports:
- port: 27017
targetPort: 27017
Apply it and wait for the pod to be ready:
kubectl apply -f mongodb.yaml
kubectl -n flink rollout status deploy/mongo-test
MongoDB is then reachable in-cluster at
mongo-service.flink.svc.cluster.local:27017 with the admin / mongo-pass
credentials from the manifest.
Upload the connector artifact
Label the JAR as a connector with the mongodb identifier, in
artifact.json:
{
"apiVersion": "cmf.confluent.io/v1",
"kind": "Artifact",
"metadata": {
"name": "mongodb-connector.jar",
"labels": {
"cmf.confluent.io/sql-artifact-type": "connector",
"cmf.confluent.io/sql-artifact-identifier": "mongodb"
}
},
"spec": {}
}
Upload it:
curl -X POST http://cmf:8080/cmf/api/v1/environments/test/artifacts \
-F 'artifact=@artifact.json;type=application/json' \
-F 'file=@flink-sql-connector-mongodb-2.0.0-1.19.jar'
Create the table
Create a table backed by a MongoDB collection. Point the uri at the service
from the manifest. The connector requires a primary key for its upsert semantics,
so declare one:
confluent flink statement create mongo-create \
--url http://cmf:8080 \
--environment test \
--compute-pool pool \
--catalog _env_test \
--database default \
--sql "CREATE TABLE \`mongo_orders\` (\`_id\` STRING, \`amount\` DOUBLE, PRIMARY KEY (\`_id\`) NOT ENFORCED) WITH ('connector' = 'mongodb', 'uri' = 'mongodb://admin:mongo-pass@mongo-service.flink.svc.cluster.local:27017/?authSource=admin', 'database' = 'testdb', 'collection' = 'orders');"
Write rows
Insert three rows. On first use of the table, CMF resolves the mongodb
artifact and ships it to the Flink cluster. The bounded INSERT reaches
COMPLETED when the documents are written.
confluent flink statement create mongo-insert \
--url http://cmf:8080 \
--environment test \
--compute-pool pool \
--catalog _env_test \
--database default \
--sql "INSERT INTO \`mongo_orders\` VALUES ('o1', 19.99), ('o2', 5.00), ('o3', 42.50);"
Confirm the documents directly in MongoDB with mongosh in the mongo-test
pod:
kubectl -n flink exec deploy/mongo-test -- \
mongosh "mongodb://admin:mongo-pass@localhost:27017/testdb?authSource=admin" \
--quiet --eval "db.orders.find().toArray()"
[
{ _id: 'o1', amount: 19.99 },
{ _id: 'o2', amount: 5 },
{ _id: 'o3', amount: 42.5 }
]
Read rows back
Query the same table to read the documents through Flink:
confluent flink statement create mongo-select \
--url http://cmf:8080 \
--environment test \
--compute-pool pool \
--catalog _env_test \
--database default \
--sql "SELECT * FROM \`mongo_orders\`;"
The query returns the three rows:
_id amount
o1 19.99
o2 5.0
o3 42.5
Clean up
Drop the table, then remove the connector and the MongoDB deployment:
confluent flink statement create mongo-drop \
--url http://cmf:8080 --environment test --compute-pool pool \
--catalog _env_test --database default \
--sql "DROP TABLE IF EXISTS \`mongo_orders\`;"
curl -X DELETE http://cmf:8080/cmf/api/v1/environments/test/artifacts/mongodb-connector.jar
kubectl delete -f mongodb.yaml