Features and SQL Support for the JDBC Driver for MongoDB®
The JDBC driver for MongoDB is free to download and supports SQL queries. The JDBC driver works with on-premise and cloud hosted MongoDB including MongoDB Atlas, and with common applications such as Tableau, Splunk, SAP Lumira, and any other query or reporting software that supports JDBC. The following table shows which SQL queries can be handled directly by the JDBC driver for MongoDB. The trial version of the JDBC driver for MongoDB has all features and no row limits. After the trial period expires, if your query produces more than 100 results, upgrade your UnityJDBC/MongoDB JDBC license here.
"_id" : ObjectId("51929a0ee4b03d5485de04a9"),
"n_nationkey" : 24,
"n_name" : "UNITED STATES",
"n_regionkey" : 1,
"n_comment" : "Largest country by population in North America."
}
"_id" : ObjectId("519299f6e4b03d5485de048d"),
"r_regionkey" : 1,
"r_name" : "AMERICA",
"r_comment" : "Includes Canada, United States, and Mexico."
}
"_id" : ObjectId("519299f6e4b03d5485de05af"),
"g_city" : "Vancouver",
"g_loc" :
{
"lat" : 49.2505,
"lon" : -123.1119,
"info" : "a coastal seaport city on the mainland of British Columbia, Canada"
},
"g_weather" : ["light rain", "rain", "heavy rain", "snow", "sun"]
}
Important Notes:
- Case-sensitive identifiers: SQL identifiers (table and field names) are interpreted as case-sensitive as they are case-sensitive in MongoDB. Use delimited-identifiers (with double-quotes) to force case-sensitivity in SQL tools and always use double-quotes for SQL reserved words (e.g. "select"). Example: SELECT a, A, "a", "A" FROM "Table" This will query a Mongo collection named Table (capital T is important) which has fields a and A. Refer to a using either a or "a". Refer to A using either A or "A".
- SQL functions: Common SQL functions including string functions (concat, substr, instr), date functions (e.g. dateadd, datediff, day), trigonometry functions, mathematical functions (e.g. abs), bit functions, and others are supported. Complete list of SQL functions supported.
Example:
SELECT concat('Clerk: ', UPPER(o_clerk)), o_totalprice5+3, dateadd('yy', 3, o_orderdate) AS orderDatePlus3Years,
CASE WHEN o_orderkey > 100 THEN 0 ELSE 1 END AS caseExample FROM orders - JDBC DatabaseMetaData and ResultSetMetaData Support: The JDBC Driver for MongoDB supports the JDBC API allowing interoperability with database software using SQL and JDBC. This includes support for DatabaseMetaData and ResultSetMetaData. Since MongoDB does not have a schema, a schema is built on connection and can be cached (see Connection Parameters for more details). For DatabaseMetaData, common API methods used include getTables, getColumns, getPrimaryKeys, getIndexInfo, getDatabaseMajorVersion, among others.
- Transactions, Connection Pooling, and DataSource Support: The JDBC Driver for MongoDB supports the JDBC API interfaces DataSource, ConnectionPoolDataSource, and XADataSource. It will also accept transaction requests such as commit and rollback. However, since MongoDB does not support transactions the driver silently ignores transaction operations and any update is automatically committed as done by MongoDB.
Feature | SQL Example | MongoDB Statement | JDBC Driver for MongoDB | UnityJDBC Virtualization Support |
---|---|---|---|---|
SELECT Clause | ||||
Select all fields from one table |
SELECT * FROM nation |
db.nation.find() | ||
Select a list of fields from one table |
SELECT n_nationkey, n_name FROM nation |
db.nation.find( { }, {"n_nationkey" : 1, "n_name" : 1, "_id" : 0}) |
||
Select with field aliases |
SELECT n_nationkey AS nkey, n_name name FROM nation |
db.nation.find( { }, {"n_nationkey" : 1, "n_name" : 1, "_id" : 0}) note: driver will rename before returning results. |
||
Select expressions |
SELECT n_nationkey + 1, 'name:'+ n_name AS name FROM nation |
|||
Select distinct |
SELECT DISTINCT n_regionkey FROM nation |
db.nation.distinct("n_regionkey", { }) | Details |
Details |
FROM Clause | ||||
One table query |
SELECT * FROM nation |
db.nation.find() | ||
Multiple table query |
SELECT * FROM nation n, region r WHERE n.n_regionkey = r.r_regionkey |
|||
Inner join clause |
SELECT * FROM nation n INNER JOIN region r ON n.n_regionkey = r.r_regionkey |
|||
Left outer join clause |
SELECT * FROM nation n LEFT OUTER JOIN region r ON n.n_regionkey = r.r_regionkey |
|||
Right outer join clause |
SELECT * FROM nation n RIGHT OUTER JOIN region r ON n.n_regionkey = r.r_regionkey |
|||
Full outer join clause |
SELECT * FROM nation n FULL OUTER JOIN region r ON n.n_regionkey = r.r_regionkey |
|||
WHERE Clause | ||||
Equality (=) comparison |
SELECT * FROM nation WHERE n_name = 'UNITED STATES' |
db.nation.find( {"n_name" : "UNITED STATES"}, { }) |
||
Greater than equal (>=) comparison |
SELECT * FROM nation WHERE n_name >= 'UNITED STATES' |
db.nation.find( {"n_name" : {$gte: "UNITED STATES"}}, { }) |
||
Greater than (>) comparison |
SELECT * FROM nation WHERE n_name > 'UNITED STATES' |
db.nation.find( {"n_name" : {$gt: "UNITED STATES"}, { }) |
||
Less than equal (<=) comparison |
SELECT * FROM nation WHERE n_name <= 'UNITED STATES' |
db.nation.find( {"n_name" : {$lte: "UNITED STATES"}} { }) |
||
Less than (<) comparison |
SELECT * FROM nation WHERE n_nationkey < 15 |
db.nation.find( {"n_nationkey" : {$lt: 15}} { }) |
||
Not equal (!= or <>) comparison |
SELECT * FROM nation WHERE n_nationkey != 5 |
db.nation.find( {"n_nationkey" : {$ne: 5}} { }) |
||
Boolean (True/False) Comparison |
SELECT * FROM nation WHERE flag = FALSE |
db.nation.find( { "flag" : false}, { }) |
||
Like comparison |
SELECT * FROM nation WHERE n_name LIKE '%A%' |
db.nation.find( { "n_name" : { "$regex" : "^.*A.*$"}}, { }) |
||
Two attribute comparison |
SELECT n_name FROM nation WHERE n_name = n_comment |
db.nation.find( { "$where" : "this.n_name == this.n_comment"}, { "n_name" : 1 , "_id" : 0}) |
||
Negation |
SELECT * FROM nation WHERE NOT (n_nationkey = 3) |
db.region.find( { "n_regionkey" : { "$ne" : 3}}, { }) |
||
AND and OR |
SELECT * FROM nation WHERE n_nationkey > 3 AND (n_name < 'F' OR n_name > 'J') |
db.region.find( {"n_nationkey" : { "$gt" : 3}, "$or" : [{"n_name" : { "$lt" : "F"}}, {"n_name" : { "$gt" : "J"}}]}, { }) |
||
NOT LIKE comparison |
SELECT * FROM region WHERE r_name NOT LIKE 'MIDD%' |
db.region.find( { "r_name" : { "$not" : { "$regex" : "^MIDD.*$"}}}, { }) |
||
Date and Timestamp Support | ||||
Date comparison with constant date value |
SELECT * FROM tbl WHERE datefld = '2014-07-04' |
db.tbl.find( { "datefld" : { "$date" : "2014-07-04T00:00:00.000Z"}}, { }) |
||
Datetime comparison with constant datetime value |
SELECT * FROM tbl WHERE datefld = '2014-07-04 13:35:42' |
db.tbl.find( { "datefld" : { "$date" : "2014-07-04T13:35:42.000Z"}}, { }) |
||
Force string comparison for date constant |
SELECT * FROM tbl WHERE datestr = str('2014-07-04 13:35:42') |
db.tbl.find( { "datefld" : "2014-07-04 13:35:42"}}, { }) |
Details | Details |
DateTime comparison as keyword |
SELECT * FROM region WHERE r_comment = CURRENT_TIMESTAMP |
|||
DateTime comparison as function |
SELECT * FROM region WHERE r_comment = CURRENT_TIMESTAMP() |
|||
Select DateTime as keyword | SELECT CURRENT_TIMESTAMP | |||
Select DateTime as function | SELECT CURRENT_TIMESTAMP() | |||
group by Clause | ||||
Group by one attribute |
SELECT n_regionkey, COUNT(*) cnt FROM nation GROUP BY n_regionkey |
db.nation.aggregate([{ "$group" : {"_id" : { "n_regionkey" : "$n_regionkey"}, "cnt" : { "$sum" : 1}}}]) |
||
Group by multiple attributes |
SELECT n_regionkey, n_name, COUNT(*) FROM nation GROUP BY n_regionkey, n_name |
db.nation.aggregate([{ "$group" : {"_id" : { "n_regionkey" : "$n_regionkey", "n_name" : "$n_name"}, "cnt" : { "$sum" : 1}}}]) |
||
Aggregate Functions | ||||
Count(*) |
SELECT COUNT(*) FROM nation |
db.nation.find({ }, { }).count() | ||
Count(attribute) |
SELECT COUNT(n_regionkey) FROM nation |
db.nation.find( {"n_nationkey" : {"$exists" : true}}, { }).count() |
||
Maximum |
SELECT MAX(n_regionkey) MAX FROM nation |
db.nation.aggregate([{ "$group" : {"_id" : null, "max" : { "$max" : "$n_regionkey"}}}]) |
||
Minimum |
SELECT MIN(n_regionkey) MIN FROM nation |
db.nation.aggregate([{ "$group" : {"_id" : null, "min" : { "$min" : "$n_regionkey"}}}]) |
||
Summation |
SELECT SUM(n_regionkey) SUM FROM nation |
db.nation.aggregate([{ "$group" : {"_id" : null, "sum" : { "$sum" : "$n_regionkey"}}}]) |
||
Average |
SELECT avg(n_regionkey) avg FROM nation |
db.nation.aggregate([{ "$group" : {"_id" : null, "avg" : { "$avg" : "$n_regionkey"}}}]) |
||
Having Clause | ||||
Having clause |
SELECT n_regionkey, COUNT(*) FROM nation GROUP BY n_regionkey HAVING COUNT(*) > 4 |
|||
Order by Clause | ||||
Order by one attribute |
SELECT * FROM nation ORDER BY n_name ASC |
db.nation.find().sort( {"n_name" : 1}) |
||
Order by multiple attributes |
SELECT * FROM nation ORDER BY n_name ASC, n_nationkey DESC |
db.nation.find().sort( {"n_name": 1, "n_nationkey" : -1} ) | ||
Order by expression |
SELECT * FROM nation ORDER BY n_nationkey+5 ASC |
|||
Limit/Offset Clause | ||||
Limit clause (single collection) |
SELECT * FROM nation LIMIT 5 |
db.nation.find().limit(5) | ||
Offset clause (single collection) |
SELECT * FROM nation LIMIT 5 offset 2 |
db.nation.find().limit(5).skip(2) | ||
Limit clause (multiple collection) |
SELECT * FROM nation INNER JOIN region ON n_regionkey = r_regionkey LIMIT 5 |
|||
Offset clause (multiple collection) |
SELECT * FROM nation INNER JOIN region ON n_regionkey = r_regionkey LIMIT 5 offset 2 |
|||
Union Clause | ||||
Two query union |
SELECT r_regionkey FROM region UNION SELECT n_regionkey FROM nation |
|||
Delete Statement | ||||
Delete with where predicate (int) |
DELETE FROM region WHERE r_regionkey > 3 |
db.region.remove( {"r_regionkey" : {$gt : 3}}) |
||
Delete with where predicate (string) |
DELETE FROM region WHERE r_name = 'ASIA' |
db.region.remove( {"r_name" : "ASIA"}) |
||
Insert Statement | ||||
Insert with specified field list |
INSERT INTO region (r_regionkey, r_name) VALUES (6, 'ANTARTICA') |
db.region.insert( {"r_regionkey" : 6, "r_name" : "ANTARTICA"}) |
Details |
|
Update Statement | ||||
Update an integer field to a constant value |
UPDATE region SET r_regionkey = 6 WHERE r_regionkey = 3 |
db.region.update( {"r_regionkey" : 3}, {$set: {"r_regionkey": 6}}, {"multi" : true}) |
||
Update a string field to a constant value |
UPDATE region SET r_name = 'ANTARTICA' WHERE r_regionkey = 3 |
db.region.update( {"r_regionkey" : 3}, {$set: {"r_name" : "ANTARTICA"}}, {"multi" : true}) |
||
Insert Statement with JSON | ||||
Insert with JSON Object |
INSERT INTO region VALUES ( '{ "r_regionkey" : 6, "r_name" : "ANTARTICA"}') |
db.region.insert( {"r_regionkey" : 6, "r_name": "ANTARTICA"}) |
Details |
Details |
Insert with JSON Object into a field |
INSERT INTO region (r_regionkey, r_name) VALUES (6, '{ "loc" : "ANTARTICA"}') |
db.region.insert( {"r_regionkey" : 6, "r_name" : {"loc": "ANTARTICA"}}) |
Details |
Details |
UPSERT (uses MongoDB save()) | ||||
UPSERT (no _id given) |
UPSERT INTO region (r_regionkey, r_name) VALUES (6, 'ANTARTICA') |
db.region.save( {"r_regionkey" : 6, "r_name": "ANTARTICA"}) |
||
UPSERT (_id given) |
UPSERT INTO region (_id, r_regionkey, r_name) VALUES (6, 6, 'ANTARTICA') |
db.region.save( {"_id" : 6, "r_regionkey" : 6, "r_name" : "ANTARTICA"}) |
||
Nested Collections | ||||
Select with nested collections |
SELECT g_city, g_loc.lat FROM georef |
db.georeg.find({ }, {"g_city" : 1, "g_loc.lat" : 1, "_id" : 0}) |
||
Select with nested collection (using SQL delimited identifier to specify nested object) |
SELECT g_city, "g_loc.lat" FROM georef |
db.georeg.find({ }, {"g_city" : 1, "g_loc.lat" : 1, "_id" : 0}) |
||
Select with nested attribute in predicate |
SELECT g_city, g_loc.lat FROM georef WHERE g_loc.lat > 48 |
db.georeg.find( {"g_loc.lat" : {$gt : 48}}, {"g_city" : 1, "g_loc.lat" : 1, "_id" : 0}) |
||
Collections with Arrays | ||||
Select with Array |
SELECT * FROM georef WHERE g_weather = 'rain' |
db.georeg.find( {"g_weather" : "rain"}, { }) |
||
Select with Array (IN syntax) |
SELECT * FROM georef WHERE 'rain' IN g_weather |
db.georeg.find( {"g_weather" : { "$regex" : "^rain$"}, { }) |
Details |
|
Select with Multiple Array Elements |
SELECT * FROM georef WHERE g_weather = 'rain' AND g_weather = 'sun' |
db.georeg.find( { "$and" : [{ "g_weather" : "rain"}, { "g_weather" : "sun"} ] }, { }) |
||
Select on Object Inside an Array |
SELECT _id, "value", "value.num" FROM arraymixedobject WHERE "value.num" = 5 |
db.arraymixedobject.find( { "value.num" : 5}, { "_id" : 1 , "value" : 1}) |
||
Select on Object Inside an Array using Array Subscripts |
SELECT _id, "value", "value.num" FROM arraymixedobject WHERE "value.2.num" = 5 |
db.arraymixedobject.find( { "value.2.num" : 5}, { "_id" : 1 , "value" : 1}) |
Details | Details |
Retrieve individual array elements by subscript |
SELECT _id, "value", "value.0", "value.1", "value.5" FROM arraymixedobject WHERE "value.2.num" = 5 |
db.arraymixedobject.find( { "value.2.num" : 5}, { "_id" : 1 , "value" : 1}) |
Details | Details |
Query objects that contain arrays (nested arrays and objects) |
SELECT num, "value.0", "value.1.num2", "value.value2", "value.1.value2.value3", "value.1.value2.1.value3" FROM nestedarray WHERE "value.1.value2.value3" < 2 |
db.nestedarray.find( { "value.1.value2.value3" : { "$lt" : 2}}, { "num" : 1 , "value" : 1 , "_id" : 0}) |
Details | Details |
DROP Table/Collection | ||||
DROP Table/Collection | DROP TABLE region | db.region.drop() | ||
Creating and Dropping Indexes | ||||
CREATE INDEX |
CREATE INDEX testIdx ON region (r_regionkey) |
db.region.ensureIndex( {"r_regionkey" : 1}, {"name" : "testIdx"}) |
||
CREATE UNIQUE INDEX (multiple fields) |
CREATE UNIQUE INDEX testIdx ON region (r_regionkey DESC, r_name ASC) |
db.region.ensureIndex( {"r_regionkey" : 1, "r_name" : 1}, {"unique" : true, "name" : "testIdx"}) |
||
CREATE HASH INDEX |
CREATE UNIQUE INDEX idx ON region (r_name) USING HASH |
db.region.ensureIndex( {"r_name" : "hashed"}, { "name" : "idx"}) |
||
DROP INDEX | DROP INDEX idx ON region | db.region.dropIndex("idx") | ||
User Management | ||||
Add a User |
INSERT INTO system.users ("user", pwd, roles) VALUES ('newuser', 'newpass', '["readWrite", "dbAdmin"]') |
db.system.users.insert( {"user" : "newuser" \, "pwd":"6e6c5af031665ca6299532edb04657c0", "roles" : ["readWrite" , "dbAdmin"]}) |
||
Remove (delete) a User |
DELETE FROM system.users WHERE "user" = 'newuser' |
db.system.users.remove( { "user" : "newuser"}) |
||
Change a User's Password |
UPDATE system.users SET pwd = 'abc' WHERE "user" = 'newuser' |
db.system.users.update( {"user" : "newuser"}, {"$set" : {"pwd":"60f037dbe185971b4ec039d442f4662b"}}) |
||
Change a User's Password and Role (permissions) |
UPDATE system.users SET pwd = 'abc', roles = '["readWrite"]' WHERE "user" = 'newuser' |
db.system.users.update( {"user" : "newuser"}, {"$set" : {"pwd":"60f037dbe185971b4ec039d442f4662b", "roles" : [ "readWrite"]}}) |
||
Note that the field user is a reserved SQL word which is why it is in double-quotes. This is optional. For more information on MongoDB permissions see MongoDB Security, Access Control, and User Permissions. |
Handling Nested Collections and Arrays
The MongoDB JDBC driver supports collections that contain subobjects and arrays. Automatic flattening is performed to simplify data access. If collection data has an attribute array, that is an array, two tables are available in the relational schema:
- data that contains all data unflattened
- data_array that contains the base attributes as well as a distinct row for each value in the array
Example: A Collection arrayint Containing an Array of Numbers |
---|
Sample JSON Document
{"_id" : ObjectId("51eac61d1bce84818dc789b9"),
"num" : 1,
"name" : "1",
"values" : [1, 2, 3, 4, 5, 6]
}
arrayint Table
_id | num | name | values (array) |
---|---|---|---|
51eac61d1bce84818dc789b9 | 1 | 1 | [1, 2, 3, 4, 5, 6] |
arrayint_values Table
_id | num | name | values (int) |
---|---|---|---|
51eac61d1bce84818dc789b9 | 1 | 1 | 1 |
51eac61d1bce84818dc789b9 | 1 | 1 | 2 |
51eac61d1bce84818dc789b9 | 1 | 1 | 3 |
51eac61d1bce84818dc789b9 | 1 | 1 | 4 |
51eac61d1bce84818dc789b9 | 1 | 1 | 5 |
51eac61d1bce84818dc789b9 | 1 | 1 | 6 |
Example: A Collection arrayobj Containing an Array of Objects |
---|
Sample JSON Document
{"_id" : ObjectId("51eaca001bceddc428c7761b"),
"values" : [{ "num" : 1 , "name" : 67}, { "num" : 2 , "name" : 68}, { "num" : 3 , "name" : 69},
{ "num" : 4 , "name" : 70}, { "num" : 5 , "name" : 71}, { "num" : 6 , "name" : 72}]
}
arrayobj Table
_id | num | name | values (array) |
---|---|---|---|
51eaca001bceddc428c7761b | 1 | 1 | [{ "num" : 1 , "name" : 67}, { "num" : 2 , "name" : 68}, { "num" : 3 , "name" : 69}, { "num" : 4 , "name" : 70}, { "num" : 5 , "name" : 71}, { "num" : 6 , "name" : 72}] |
arrayobj_values Table
_id | num | name |
---|---|---|
51eaca001bceddc428c7761b | 1 | 67 |
51eaca001bceddc428c7761b | 2 | 68 |
51eaca001bceddc428c7761b | 3 | 69 |
51eaca001bceddc428c7761b | 4 | 70 |
51eaca001bceddc428c7761b | 5 | 71 |
51eaca001bceddc428c7761b | 6 | 72 |
Example: A Collection nest4 containing Multiple Levels of Nested Arrays and Object |
---|
Sample JSON Document
{"_id" : ObjectId("542ec0c9486e886dd6a2238d"),
"anum" : 1,
"aname" : "a1",
"avalues" : [{ "bnum" : 11 , "bname" : "b11" , "bvalues" :
[ { "cnum" : 111 , "cname" : "c111" , "cvalues" :
[ { "dnum" : 1111 , "dname" : "d1111"} , { "dnum" : 2111 , "dname" : "d2111"} ,
{ "dnum" : 3111 , "dname" : "d3111"}]} ,
{ "cnum" : 211 , "cname" : "c211" , "cvalues" :
[ { "dnum" : 1211 , "dname" : "d1211"} , { "dnum" : 2211 , "dname" : "d2211"} ,
{ "dnum" : 3211 , "dname" : "d3211"}]}]},
{ "bnum" : 21 , "bname" : "b21" , "bvalues" :
[ { "cnum" : 121 , "cname" : "c121" , "cvalues" :
[ { "dnum" : 1121 , "dname" : "d1121"} , { "dnum" : 2121 , "dname" : "d2121"} ,
{ "dnum" : 3121 , "dname" : "d3121"}]} ,
{ "cnum" : 221 , "cname" : "c221" , " cvalues" :
[ { "dnum" : 1221 , "dname" : "d1221"} , { "dnum" : 2221 , "dname" : "d2221"} ,
{ "dnum" : 3221 , "dname" : "d3221"}]}]},
{ "bnum" : 31 , "bname" : "b31" , "bvalues" :
[ { "cnum" : 131 , "cname" : "c131" , "cvalues" :
[ { "dnum" : 1131 , "dname" : "d1131"} , { "dnum" : 2131 , "dname" : "d2131"} ,
{ "dnum" : 3131 , "dname" : "d3131"}]} ,
{ "cnum" : 231 , "cname" : "c231" , "cvalues" :
[ { "dnum" : 1231 , "dname" : "d1231"} , { "dnum" : 2231 , "dname" : "d2231"} ,
{ "dnum" : 3231 , "dname" : "d3231"}]}]}]
}
nest4 Table
_id | anum | aname | avalues (array) |
---|---|---|---|
542ec0c9486e886dd6a2238d | 1 | a1 | (full JSON of avalues) |
nest4_avalues Table
_id | anum | aname | bnum | bname |
---|---|---|---|---|
542ec0c9486e886dd6a2238d | 1 | a1 | 11 | b11 |
542ec0c9486e886dd6a2238d | 1 | a1 | 21 | b21 |
542ec0c9486e886dd6a2238d | 1 | a1 | 31 | b31 |
nest4_avalues_bvalues Table
_id | anum | aname | bnum | bname | cnum | cname |
---|---|---|---|---|---|---|
542ec0c9486e886dd6a2238d | 1 | a1 | 11 | b11 | 111 | c111 |
542ec0c9486e886dd6a2238d | 1 | a1 | 11 | b11 | 211 | c211 |
542ec0c9486e886dd6a2238d | 1 | a1 | 21 | b21 | 121 | c121 |
542ec0c9486e886dd6a2238d | 1 | a1 | 21 | b21 | 221 | c221 |
542ec0c9486e886dd6a2238d | 1 | a1 | 31 | b31 | 131 | c131 |
542ec0c9486e886dd6a2238d | 1 | a1 | 31 | b31 | 231 | c231 |
nest4_avalues_bvalues_cvalues Table
_id | anum | aname | bnum | bname | cnum | cname | dnum | dname |
---|---|---|---|---|---|---|---|---|
542ec0c9486e886dd6a2238d | 1 | a1 | 11 | b11 | 111 | c111 | 1111 | d1111 |
542ec0c9486e886dd6a2238d | 1 | a1 | 11 | b11 | 111 | c111 | 2111 | d2111 |
542ec0c9486e886dd6a2238d | 1 | a1 | 11 | b11 | 111 | c111 | 3111 | d3111 |
542ec0c9486e886dd6a2238d | 1 | a1 | 11 | b11 | 211 | c211 | 1211 | d1211 |
542ec0c9486e886dd6a2238d | 1 | a1 | 11 | b11 | 211 | c211 | 2211 | d2211 |
542ec0c9486e886dd6a2238d | 1 | a1 | 11 | b11 | 211 | c211 | 3211 | d3211 |
... |
Mongo and MongoDB are trademarks of 10gen, Inc.