Mongo

ArcadeDB provides support for both MongoDB Query Language and MongoDB protocol.

If you’re using ArcadeDB as embedded, please add the dependency to the arcadedb-mongodbw library. If you’re using Maven include this dependency in your pom.xml file.

<dependency>
    <groupId>com.arcadedb</groupId>
    <artifactId>arcadedb-mongodbw</artifactId>
    <version>26.5.1</version>
</dependency>

MongoDB Query Language

If you want to use MongoDB Query Language from Java API, you can simply keep the relevant jars in your classpath and execute a query or a command with "mongo" as language.

Example:

// CREATE A NEW DATABASE
Database database = new DatabaseFactory("heroes").create();

// CREATE THE DOCUMENT TYPE 'HEROES'
database.getSchema().createDocumentType("Heroes");

// CREATE A NEW DOCUMENT
database.transaction((tx) -> {
  database.newDocument("Heroes").set("name", "Jay").set("lastName", "Miner").set("id", i).save();
});

// EXECUTE A QUERY USING MONGO AS QUERY LANGUAGE
for (ResultSet resultset = database.query("mongo", // <-- USE 'mongo' INSTEAD OF 'sql'
    "{ collection: 'Heroes', query: { $and: [ { name: { $eq: 'Jay' } }, { lastName: { $exists: true } }, { lastName: { $eq: 'Miner' } }, { lastName: { $ne: 'Miner22' } } ], $orderBy: { id: 1 } } }"); resultset.hasNext(); ++i) {
  Result doc = resultset.next();
  ...
}

For more information on the MongoDB query language see: MongoDB CRUD Operations

Mongo queries through Postgres Driver

You can execute a Mongo query against ArcadeDB server by using the Postgres driver and prefixing the query with {mongo}. Example:

"{mongo} { collection: 'Heroes', query: { $and: [ { name: { $eq: 'Jay' } }, { lastName: { $exists: true } }, { lastName: { $eq: 'Miner' } } ] } }"

ArcadeDB server will execute the query { collection: 'Heroes', query: { $and: [ { name: { $eq: 'Jay' } }, { lastName: { $exists: true } }, { lastName: { $eq: 'Miner' } } ] } } using the Mongo query language.

Mongo queries through HTTP/JSON

You can execute a Mongo query against ArcadeDB server by using HTTP/JSON API. Example of executing an idempotent query with HTTP GET command:

curl "http://localhost:2480/query/graph/mongo/{ collection: 'Heroes', query: { $and: [ { name: { $eq: 'Jay' } }, { lastName: { $exists: true } }, { lastName: { $eq: 'Miner' } } ]} }"

You can also execute the same query in HTTP POST, passing the language and query in payload:

curl -X POST "http://localhost:2480/query/graph" -d "{'language': 'mongo', 'command': '{ collection: \"Heroes\", query: { $and: [ { name: { $eq: \"Jay\" } }, { lastName: { $exists: true } }, { lastName: { $eq: \"Miner\" } } ] } }\"}"

MongoDB Protocol Plugin

If your application is written for MongoDB and you’d like to run it with ArcadeDB instead, you can simply replace the MongoDB server with ArcadeDB server with the MongoDB Plugin installed. This plugin supports MongoDB BSON Network protocol. In this way you can use any MongoDB driver for any supported programming language.

ArcadeDB Server supports a subset of the MongoDB protocol, like CRUD operations and queries.

To start the MongoDB plugin, enlist it in the server.plugins settings. To specify multiple plugins, use the comma , as separator.

Example to start ArcadeDB with the MongoDB Plugin:

~/arcadedb $ bin/server.sh -Darcadedb.server.plugins="MongoDB:com.arcadedb.mongo.MongoDBProtocolPlugin"

If you’re using MS Windows OS, replace server.sh with server.bat.

In case you’re running ArcadeDB with Docker, use -e to pass settings (Port 27017 is the default MongoDB binary port):

docker run --rm -p 2480:2480 -p 2424:2424 -p27017:27017 \
       --env JAVA_OPTS="-Darcadedb.server.rootPassword=playwithdata \
          -Darcadedb.server.plugins=MongoDB:com.arcadedb.mongo.MongoDBProtocolPlugin " \
          arcadedata/arcadedb:latest

The Server output will contain this line:

2018-10-09 18:47:01:692 INFO  <ArcadeDB_0> - MongoDB Protocol plugin started [ArcadeDBServer]

Supported commands

The plugin implements a subset of the MongoDB protocol, focused on CRUD operations, queries and index creation:

Command Driver helpers

find, count, aggregate

find(), countDocuments(), aggregate()

insert

insertOne(), insertMany()

update

updateOne(), updateMany(), replaceOne(), replaceMany()

delete

deleteOne(), deleteMany()

create

createCollection()

createIndexes

createIndex(), createIndexes()

Updating and deleting documents

The update and delete commands accept the same filter operators as find ($eq, $ne, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not, $exists, …​).

// Delete the first matching document
db.doc.deleteOne({ test: { $eq: "abcde" } })

// Delete all matching documents
db.doc.deleteMany({ counter: { $gte: 5 } })

// Replace the whole document (replaceOne / replaceMany)
db.doc.replaceOne({ test: { $eq: "abcde" } }, { test: "vwxyz" })

// Update with operators ($set, $unset, $inc)
db.doc.updateOne({ test: "v2" }, { $set: { name: "Jay" } })
db.doc.updateMany({ counter: { $gte: 8 } }, { $inc: { counter: 100 } })
db.doc.updateOne({ test: "v1" }, { $unset: { counter: "" } })

// Upsert: insert when nothing matches
db.doc.updateOne({ test: "missing" }, { $set: { counter: 999 } }, { upsert: true })

Notes:

  • deleteOne(), updateOne() and replaceOne() affect a single matching document; deleteMany() and updateMany() affect all matches.

  • A replacement document (no $-prefixed keys) fully replaces the matched document’s fields. The supported update operators are $set, $unset and $inc.

  • With upsert: true, when no document matches a new one is inserted, seeded from the filter’s equality conditions plus the update, and its generated _id is returned.

Authentication

The MongoDB Protocol Plugin supports authentication through the SASL PLAIN mechanism (RFC 4616). Credentials are validated against the ArcadeDB server users, exactly like the PostgreSQL protocol.

Because ArcadeDB stores passwords as one-way hashes, the challenge-response mechanisms SCRAM-SHA-1 and SCRAM-SHA-256 (the default negotiated by most MongoDB drivers and by mongosh) cannot be supported: they would require the clear-text password to be available on the server side. For this reason the client must explicitly request the PLAIN mechanism.

Example using a connection string:

mongosh "mongodb://root:playwithdata@localhost:27017/mydb?authMechanism=PLAIN"

Or, from an already opened shell:

db.auth({ user: "root", pwd: "playwithdata", mechanism: "PLAIN" })

The user and pwd are the ArcadeDB server credentials, and the authentication database is checked against the databases the user is authorized to access.

The PLAIN mechanism transmits the credentials in clear text. In production always use it over a TLS-encrypted connection, the same recommendation that applies to the PostgreSQL wire protocol.

Index management

The MongoDB Protocol Plugin supports the createIndexes command, used by the driver helpers createIndex() and createIndexes(). Each requested index is mapped to an ArcadeDB LSM-Tree index over the same property list.

// Single-field index
db.doc.createIndex({ test: 1 })

// Unique index
db.doc.createIndex({ email: 1 }, { unique: true })

// Compound index
db.doc.createIndex({ lastName: 1, firstName: -1 })

Notes:

  • If the target collection does not exist yet, it is created automatically (the response reports createdCollectionAutomatically: true).

  • Because MongoDB collections are schemaless, properties that are not yet declared on the type are kept free-form and the index serializes their keys as strings, preserving the stored value type.

  • The sort direction (1 ascending, -1 descending) is accepted for compatibility but ignored: ArcadeDB LSM-Tree indexes can be scanned in both directions.

  • Re-creating an existing index is a no-op, matching MongoDB semantics.

  • Specialized index types (text, 2dsphere, hashed, …​) are created as standard LSM-Tree indexes on the indexed fields.