« Mongodb » : différence entre les versions
(→Ubuntu) |
|||
(84 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
[[Category:SQL]] | |||
= Description = | |||
MongoDB stores data records as BSON documents gathered in collections (= SQL table). BSON is a binary representation of JSON documents.<br> | |||
MongoDB documents are composed of field-and-value pairs. The value of a field can be any of the BSON [https://www.mongodb.com/docs/manual/reference/bson-types/#std-label-bson-types data types]. | |||
<kode lang='json'> | |||
var mydoc = { | |||
// field _id is a primary key | |||
_id: ObjectId("5099803df3f4948bd2f98391"), | |||
// name holds an embedded document that contains the fields first and last | |||
name: { first: "Alan", last: "Turing" }, | |||
birth: new Date('Jun 23, 1912'), | |||
death: new Date('Jun 07, 1954'), | |||
contribs: [ "Turing machine", "Turing test", "Turingery" ], | |||
views : NumberLong(1250000) | |||
} | |||
</kode> | |||
= Connect and authenticate = | = Connect and authenticate = | ||
<kode lang='bash'> | <kode lang='bash'> | ||
# connect | # connect | ||
mongosh mongodb://localhost:27017 | |||
# alias | # alias | ||
mongosh | |||
# connect and authenticate, use an environment variable to hide the password | # connect and authenticate, use an environment variable to hide the password | ||
mongosh "mongodb://user:${DBPASSWORD}@<host>:<port>/admin?authSource=admin" | |||
</kode> | </kode> | ||
Ligne 15 : | Ligne 32 : | ||
db.auth("username", passwordPrompt()) | db.auth("username", passwordPrompt()) | ||
</kode> | |||
= Database = | |||
<kode lang='mongodb'> | |||
// list the databases | |||
show dbs | |||
// switch to [dbname] | |||
use [dbname] | |||
// create a new database with a new collection (and insert data) | |||
use [newdbname] | |||
db.[newCollectionName].insertOne( { x: 1 } ) | |||
// drop the current database | |||
db.dropDatabase() | |||
</kode> | |||
= [https://www.mongodb.com/docs/manual/reference/method/db.createCollection/#mongodb-method-db.createCollection Collection] = | |||
It gathers documents and is an equivalent of an SQL table.<br> | |||
A collection does not require its documents to have the same schema (the same set of fields and the same data types) | |||
<kode lang='mongodb'> | |||
// list collections | |||
db.getCollectionInfos() | |||
db.runCommand('listCollections') | |||
db.createCollection("[collectionName]", | |||
{ | |||
[option]: [value] | |||
})¨ | |||
// empty collection | |||
db.myCollection.deleteMany({}) | |||
</kode> | |||
== [https://www.mongodb.com/docs/manual/core/views/ View] == | |||
It is a read-only queryable object whose contents are defined by an aggregation pipeline on other collections or views.<br> | |||
It is computed when you read the view, and it is not stored to disk.<br> | |||
[https://www.mongodb.com/docs/manual/core/views/create-view/#std-label-manual-views-create Create and Query a View] | |||
<kode lang='mongodb'> | |||
// 2 syntaxes to create a view | |||
db.createCollection( | |||
"<viewName>", | |||
{ | |||
"viewOn" : "<source>", | |||
"pipeline" : [<pipeline>], | |||
"collation" : { <collation> } | |||
} | |||
) | |||
db.createView( | |||
"<viewName>", | |||
"<source>", | |||
[<pipeline>], | |||
{ | |||
"collation" : { <collation> } | |||
} | |||
) | |||
// drop a view | |||
db.<viewName>.drop() | |||
</kode> | |||
== [https://www.mongodb.com/docs/manual/core/timeseries-collections/#std-label-manual-timeseries-collection Time Series Collections] == | |||
MongoDB treats time series collections as writable non-materialized views backed by an internal collection. | |||
[https://www.mongodb.com/docs/manual/core/timeseries/timeseries-procedures/#std-label-timeseries-create-query-procedures Create and Query a Time Series Collection] | |||
<kode lang='mongodb'> | |||
db.createCollection( | |||
"weather", | |||
{ | |||
timeseries: { | |||
timeField: "timestamp", | |||
metaField: "metadata", | |||
granularity: "seconds" | |||
}}) | |||
</kode> | |||
=== [https://www.mongodb.com/developer/products/mongodb/preparing-tsdata-with-densify-and-fill/ Densify and fill] === | |||
* {{boxx|[https://www.mongodb.com/docs/manual/reference/operator/aggregation/densify/ densify]}} allows to create missing spots in the TS | |||
** {{boxx|bounds: "full"}} spans from the full range of the original TS | |||
** {{boxx|bounds: [ <from>, <to> ]}} spans from the defined bounds | |||
* {{boxx|[https://www.mongodb.com/docs/manual/reference/operator/aggregation/fill/ fill]}} allows to set values in those new spots. | |||
** {{boxx|locf}} to get the same value as the previous spot | |||
** {{boxx|linear}} to get the linear interpolation between the previous and the next point | |||
<kode lang='mongodb'> | |||
[{ | |||
$densify: { | |||
field: "event", | |||
range: { | |||
step: 15, | |||
unit: "minute", | |||
bounds: "full" | |||
} | |||
} | |||
}, { | |||
$fill: { | |||
sortBy: { | |||
event: 1 | |||
}, | |||
output: { | |||
capacity: { | |||
method: "locf" | |||
} | |||
} | |||
} | |||
}] | |||
</kode> | |||
= [https://www.mongodb.com/docs/manual/tutorial/query-documents/ Query] = | |||
== [https://www.mongodb.com/docs/manual/tutorial/project-fields-from-query-result find] == | |||
<kode lang='mongodb'> | |||
db.myCollection.find( { } ) | |||
// SELECT * | |||
db.myCollection.find( { item: 1, status: 1 } ) | |||
// SELECT _id, item, status | |||
// _id is returned by default | |||
db.myCollection.find( { item: 1, status: 1, _id: 0 } ) | |||
// SELECT item, status | |||
db.myCollection.find( { status: 0 } ) | |||
// returns all fields but status | |||
</kode> | |||
== [https://www.mongodb.com/docs/manual/reference/operator/query/ Query and Projection Operators)] == | |||
<kode lang='mongodb'> | |||
db.myCollection.find( { name: "item1" } ) | |||
// SELECT ... WHERE name = "item1" | |||
db.myCollection.find( { name: /^item/ } ) | |||
// SELECT ... WHERE name LIKE "item%" | |||
db.myCollection.find( { status: "active", quantity: { $lt: 10 } } ) | |||
// SELECT ... WHERE status = "active" AND quantity < 10 | |||
db.myCollection.find( { $or: [ { status: "active" }, { qty: { $lt: 10 } } ] } ) | |||
// SELECT ... WHERE status = "active" OR quantity < 10 | |||
db.myCollection.find( { status: { $in: [ "active", "deleted" ] } } ) | |||
// SELECT ... WHERE status in ("active", "deleted") | |||
</kode> | |||
* [https://www.mongodb.com/docs/manual/reference/operator/query/regex regex] | |||
= Aggregation = | |||
<kode lang='mongodb'> | |||
db.myCollection.aggregate( | |||
[ | |||
{ }, | |||
{ } | |||
] | |||
) | |||
</kode> | |||
== [https://www.mongodb.com/docs/manual/reference/operator/aggregation/match match] == | |||
<kode lang='mongodb'> | |||
$match : { name : "item1" } | |||
</kode> | |||
== [https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort sort] == | |||
<kode lang='mongodb'> | |||
$sort : { property1 : 1, property2: -1 } } | |||
// ORDER BY property1 ASC, property2 DESC | |||
</kode> | |||
== [https://www.mongodb.com/docs/manual/reference/operator/aggregation/project project] == | |||
<kode lang='mongodb'> | |||
$project: { | |||
_id: 0, // hide _id | |||
property2: "$_id.property1", // include _id.property and rename as property2 | |||
property3: 1 // include property3 | |||
} | |||
</kode> | |||
== [https://www.mongodb.com/docs/manual/reference/operator/aggregation/group/ group] == | |||
<kode lang='mongodb'> | |||
{ | |||
$group : { | |||
_id : "$item", | |||
totalAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } } | |||
} | |||
}, | |||
{ | |||
$match: { "totalAmount": { $gte: 100 } } | |||
} | |||
// GROUP BY item HAVING totalAmount > 100 | |||
$group: { | |||
_id: null, | |||
count: { $count: { } } | |||
} | |||
// SELECT COUNT(*) | |||
{ $group: { _id: { state: "$state", city: "$city" }, cityTotalPopulation: { $sum: "$population" } } }, | |||
{ $group: { _id: "$_id.state", avgCityPopulation: { $avg: "$cityTotalPopulation" } } } | |||
// SELECT SUM(population) AS cityTotalPopulation ... GROUP BY state, city | |||
// SELECT AVG(cityTotalPopulation) ... GROUP BY state | |||
// group and project | |||
{ | |||
$group: { | |||
_id: { | |||
metadata: "$metadata", | |||
}, | |||
value: { | |||
$avg: "$value", | |||
}, | |||
count: { | |||
$count: {}, | |||
} | |||
} | |||
}, | |||
{ | |||
$project: { | |||
_id: 0, | |||
metadata: "$_id.metadata", | |||
value: 1, | |||
count: 1 | |||
} | |||
} | |||
</kode> | |||
== [https://www.mongodb.com/docs/manual/reference/operator/aggregation/densify densify] == | |||
Creates new documents in a sequence of documents where certain values in a field are missing. | |||
<kode lang='mongodb'> | |||
{ | |||
$densify: { | |||
field: "timestamp", | |||
partitionByFields: ["metadata", "value"], | |||
range: { | |||
step: 60, | |||
unit: "minute", | |||
bounds: [ | |||
new Date("2024-03-25T12:00:00.000Z"), | |||
new Date("2024-03-26T12:00:00.000Z"), | |||
], | |||
}, | |||
}, | |||
} | |||
</kode> | |||
== [https://www.mongodb.com/docs/manual/reference/operator/aggregation/fill fill] == | |||
<kode lang='mongodb'> | |||
{ | |||
$fill: { | |||
sortBy: { timestamp: 1 }, | |||
partitionBy: { "metadata": "$metadata" }, | |||
output: { | |||
metadata: { | |||
method: "locf", | |||
}, | |||
value: { | |||
method: "locf", | |||
}, | |||
}, | |||
}, | |||
} | |||
</kode> | |||
= Index = | |||
<kode lang='mongodb'> | |||
// list indexes | |||
db.myCollection.getIndexes() | |||
// create an index on name | |||
db.myCollection.createIndex( { name: 1 } ) | |||
// for a single-field index, the sort order (ascending or descending) of the index key does not matter because MongoDB can traverse the index in either direction. | |||
db.myCollection.dropIndex( "index name" ) | |||
db.myCollection.dropIndex( { name: 1 } ) | |||
</kode> | </kode> | ||
Ligne 26 : | Ligne 313 : | ||
This may happen because the {{boxx|mongorestore}} command point to a backup sub-folder not to the backup folder itself. | This may happen because the {{boxx|mongorestore}} command point to a backup sub-folder not to the backup folder itself. | ||
= [https://www.mongodb.com/ | = [https://www.mongodb.com/docs/manual/core/authentication/#std-label-authentication Authentication] = | ||
<kode lang='mongodb'> | <kode lang='mongodb'> | ||
// list the users of the current database | |||
db.getUsers() | |||
db.runCommand('usersInfo') | |||
// get info of a specific user | |||
db.getUser("tom", { showCredentials: true, showPrivileges: true, showAuthenticationRestrictions: true }) | |||
// create admin | // create admin | ||
use admin | use admin | ||
Ligne 38 : | Ligne 332 : | ||
) | ) | ||
// create a user | // create a user for the demo database | ||
use demo | use demo | ||
db.createUser( | db.createUser( | ||
{ | { | ||
user: " | user: "tom", | ||
pwd: passwordPrompt(), // or cleartext password | pwd: passwordPrompt(), // or cleartext password | ||
roles: [ { role: "readWrite", db: "demo" }, | roles: [ { role: "readWrite", db: "demo" }, | ||
Ligne 48 : | Ligne 342 : | ||
} | } | ||
) | ) | ||
// change password | |||
use admin | |||
db.changeUserPassword("tom", "secretpassword") | |||
db.changeUserPassword("tom", passwordPrompt()) | |||
// delete a user | |||
db.dropUser("tom") | |||
</kode> | </kode> | ||
Ligne 54 : | Ligne 356 : | ||
authorization: "enabled" | authorization: "enabled" | ||
</filebox> | </filebox> | ||
= Bash = | |||
<kode lang='bash'> | |||
mongo <<EOF | |||
use admin | |||
db.auth("admin", "${MONGODBADMINPWD}") | |||
use mydb | |||
db.dropDatabase() | |||
EOF | |||
</kode> | |||
= Compass = | = Compass = | ||
= Installation = | = [https://www.mongodb.com/docs/manual/installation/#mongodb-installation-tutorials Installation] = | ||
== Windows == | == Windows == | ||
<kode lang='ps'> | <kode lang='ps'> | ||
Ligne 74 : | Ligne 386 : | ||
|} | |} | ||
* Install the [https://www.mongodb.com/docs/database-tools/installation/installation-windows/ Database Tools] in {{boxx|C:\Program Files\MongoDB\Tools}} | * Install the [https://www.mongodb.com/docs/database-tools/installation/installation-windows/ Database Tools] in {{boxx|C:\Program Files\MongoDB\Tools}} | ||
== [https://wiki.archlinux.org/title/MongoDB#Installation Archlinux] == | |||
<kode lang='bash'> | |||
yay mongodb-bin | |||
# install dependencies mongodb-bin-debug, mongosh-bin, mongosh-bin-debug | |||
# GUI | |||
yay mongodb-compass | |||
# tools | |||
yay mongodb-tools | |||
# service | |||
sc-status mongodb.service | |||
</kode> | |||
== [https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-ubuntu/ Ubuntu] == | |||
<kode lang='bash'> | |||
# import the MongoDB public GPG key | |||
curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | \ | |||
sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg \ | |||
--dearmor | |||
# create the list file | |||
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/8.0 multiverse" | \ | |||
sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list | |||
# reload the Package Database and install | |||
sudo apt-get update | |||
sudo apt-get install -y mongodb-org | |||
# the following packages is installed: | |||
# mongodb-database-tools mongodb-mongosh mongodb-org-database mongodb-org-database-tools-extra mongodb-org-mongos | |||
# mongodb-org-server mongodb-org-shell mongodb-org-tools | |||
# a user 'mongodb' and a group 'mongodb' are created. | |||
# start the service | |||
sc-start mongod | |||
</kode> | |||
=== Error === | |||
<pre> | |||
src/third_party/tcmalloc/dist/tcmalloc/system-alloc.cc:755] MmapAligned() failed - unable to allocate with tag (hint=0x6c0200000000, size=1073741824, alignment=1073741824) - is something limiting address placement? | |||
src/third_party/tcmalloc/dist/tcmalloc/arena.cc:48] CHECK in Alloc: FATAL ERROR: Out of memory trying to allocate internal tcmalloc data (bytes=131072, object-size=640); is something preventing mmap from succeeding (sandbox, VSS limitations)? | |||
</pre> |
Dernière version du 31 octobre 2024 à 21:58
Description
MongoDB stores data records as BSON documents gathered in collections (= SQL table). BSON is a binary representation of JSON documents.
MongoDB documents are composed of field-and-value pairs. The value of a field can be any of the BSON data types.
var mydoc = { // field _id is a primary key _id: ObjectId("5099803df3f4948bd2f98391"), // name holds an embedded document that contains the fields first and last name: { first: "Alan", last: "Turing" }, birth: new Date('Jun 23, 1912'), death: new Date('Jun 07, 1954'), contribs: [ "Turing machine", "Turing test", "Turingery" ], views : NumberLong(1250000) } |
Connect and authenticate
# connect mongosh mongodb://localhost:27017 # alias mongosh # connect and authenticate, use an environment variable to hide the password mongosh "mongodb://user:${DBPASSWORD}@<host>:<port>/admin?authSource=admin" |
Authenticate
db.auth("username", "pwd") db.auth("username", passwordPrompt()) |
Database
// list the databases show dbs // switch to [dbname] use [dbname] // create a new database with a new collection (and insert data) use [newdbname] db.[newCollectionName].insertOne( { x: 1 } ) // drop the current database db.dropDatabase() |
Collection
It gathers documents and is an equivalent of an SQL table.
A collection does not require its documents to have the same schema (the same set of fields and the same data types)
// list collections db.getCollectionInfos() db.runCommand('listCollections') db.createCollection("[collectionName]", { [option]: [value] })¨ // empty collection db.myCollection.deleteMany({}) |
View
It is a read-only queryable object whose contents are defined by an aggregation pipeline on other collections or views.
It is computed when you read the view, and it is not stored to disk.
Create and Query a View
// 2 syntaxes to create a view db.createCollection( "<viewName>", { "viewOn" : "<source>", "pipeline" : [<pipeline>], "collation" : { <collation> } } ) db.createView( "<viewName>", "<source>", [<pipeline>], { "collation" : { <collation> } } ) // drop a view db.<viewName>.drop() |
Time Series Collections
MongoDB treats time series collections as writable non-materialized views backed by an internal collection. Create and Query a Time Series Collection
db.createCollection( "weather", { timeseries: { timeField: "timestamp", metaField: "metadata", granularity: "seconds" }}) |
Densify and fill
- densify allows to create missing spots in the TS
- bounds: "full" spans from the full range of the original TS
- bounds: [ <from>, <to> ] spans from the defined bounds
- fill allows to set values in those new spots.
- locf to get the same value as the previous spot
- linear to get the linear interpolation between the previous and the next point
[{ $densify: { field: "event", range: { step: 15, unit: "minute", bounds: "full" } } }, { $fill: { sortBy: { event: 1 }, output: { capacity: { method: "locf" } } } }] |
Query
find
db.myCollection.find( { } ) // SELECT * db.myCollection.find( { item: 1, status: 1 } ) // SELECT _id, item, status // _id is returned by default db.myCollection.find( { item: 1, status: 1, _id: 0 } ) // SELECT item, status db.myCollection.find( { status: 0 } ) // returns all fields but status |
Query and Projection Operators)
db.myCollection.find( { name: "item1" } ) // SELECT ... WHERE name = "item1" db.myCollection.find( { name: /^item/ } ) // SELECT ... WHERE name LIKE "item%" db.myCollection.find( { status: "active", quantity: { $lt: 10 } } ) // SELECT ... WHERE status = "active" AND quantity < 10 db.myCollection.find( { $or: [ { status: "active" }, { qty: { $lt: 10 } } ] } ) // SELECT ... WHERE status = "active" OR quantity < 10 db.myCollection.find( { status: { $in: [ "active", "deleted" ] } } ) // SELECT ... WHERE status in ("active", "deleted") |
Aggregation
db.myCollection.aggregate( [ { }, { } ] ) |
match
$match : { name : "item1" } |
sort
$sort : { property1 : 1, property2: -1 } } // ORDER BY property1 ASC, property2 DESC |
project
$project: { _id: 0, // hide _id property2: "$_id.property1", // include _id.property and rename as property2 property3: 1 // include property3 } |
group
{ $group : { _id : "$item", totalAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } } } }, { $match: { "totalAmount": { $gte: 100 } } } // GROUP BY item HAVING totalAmount > 100 $group: { _id: null, count: { $count: { } } } // SELECT COUNT(*) { $group: { _id: { state: "$state", city: "$city" }, cityTotalPopulation: { $sum: "$population" } } }, { $group: { _id: "$_id.state", avgCityPopulation: { $avg: "$cityTotalPopulation" } } } // SELECT SUM(population) AS cityTotalPopulation ... GROUP BY state, city // SELECT AVG(cityTotalPopulation) ... GROUP BY state // group and project { $group: { _id: { metadata: "$metadata", }, value: { $avg: "$value", }, count: { $count: {}, } } }, { $project: { _id: 0, metadata: "$_id.metadata", value: 1, count: 1 } } |
densify
Creates new documents in a sequence of documents where certain values in a field are missing.
{ $densify: { field: "timestamp", partitionByFields: ["metadata", "value"], range: { step: 60, unit: "minute", bounds: [ new Date("2024-03-25T12:00:00.000Z"), new Date("2024-03-26T12:00:00.000Z"), ], }, }, } |
fill
{ $fill: { sortBy: { timestamp: 1 }, partitionBy: { "metadata": "$metadata" }, output: { metadata: { method: "locf", }, value: { method: "locf", }, }, }, } |
Index
// list indexes db.myCollection.getIndexes() // create an index on name db.myCollection.createIndex( { name: 1 } ) // for a single-field index, the sort order (ascending or descending) of the index key does not matter because MongoDB can traverse the index in either direction. db.myCollection.dropIndex( "index name" ) db.myCollection.dropIndex( { name: 1 } ) |
Backup and restore
# restore the backup folder dump to the local mongodb instance mongorestore dump/ |
don't know what to do with file while restore
This may happen because the mongorestore command point to a backup sub-folder not to the backup folder itself.
Authentication
// list the users of the current database db.getUsers() db.runCommand('usersInfo') // get info of a specific user db.getUser("tom", { showCredentials: true, showPrivileges: true, showAuthenticationRestrictions: true }) // create admin use admin db.createUser( { user: "admin", pwd: "mypwd", roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] } ) // create a user for the demo database use demo db.createUser( { user: "tom", pwd: passwordPrompt(), // or cleartext password roles: [ { role: "readWrite", db: "demo" }, { role: "read", db: "finances" } ] } ) // change password use admin db.changeUserPassword("tom", "secretpassword") db.changeUserPassword("tom", passwordPrompt()) // delete a user db.dropUser("tom") |
/etc/mongod.conf |
security: authorization: "enabled" |
Bash
mongo <<EOF use admin db.auth("admin", "${MONGODBADMINPWD}") use mydb db.dropDatabase() EOF |
Compass
Installation
Windows
choco install mongodb mongodb-shell |
Key | Value |
---|---|
Service name | MongoDB |
Data directory | C:\Program Files\MongoDB\Server\6.0\data\ |
Log directory | C:\Program Files\MongoDB\Server\6.0\log\ |
- Install the Database Tools in C:\Program Files\MongoDB\Tools
Archlinux
yay mongodb-bin # install dependencies mongodb-bin-debug, mongosh-bin, mongosh-bin-debug # GUI yay mongodb-compass # tools yay mongodb-tools # service sc-status mongodb.service |
Ubuntu
# import the MongoDB public GPG key curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | \ sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg \ --dearmor # create the list file echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/8.0 multiverse" | \ sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list # reload the Package Database and install sudo apt-get update sudo apt-get install -y mongodb-org # the following packages is installed: # mongodb-database-tools mongodb-mongosh mongodb-org-database mongodb-org-database-tools-extra mongodb-org-mongos # mongodb-org-server mongodb-org-shell mongodb-org-tools # a user 'mongodb' and a group 'mongodb' are created. # start the service sc-start mongod |
Error
src/third_party/tcmalloc/dist/tcmalloc/system-alloc.cc:755] MmapAligned() failed - unable to allocate with tag (hint=0x6c0200000000, size=1073741824, alignment=1073741824) - is something limiting address placement? src/third_party/tcmalloc/dist/tcmalloc/arena.cc:48] CHECK in Alloc: FATAL ERROR: Out of memory trying to allocate internal tcmalloc data (bytes=131072, object-size=640); is something preventing mmap from succeeding (sandbox, VSS limitations)?