Chapter 4 Manipulate Data
4.1 Insert
The easiest way to insert data is from an R data frame. The data frame columns will automatically be mapped to keys in the JSON records:
#> List of 5
#> $ nInserted : num 150
#> $ nMatched : num 0
#> $ nRemoved : num 0
#> $ nUpserted : num 0
#> $ writeErrors: list()
This is basically the inverse from mongo$find()
which converts the collection back into a Data Frame:
#> Sepal_Length Sepal_Width Petal_Length Petal_Width Species
#> 1 5.1 3.5 1.4 0.2 setosa
#> 2 4.9 3.0 1.4 0.2 setosa
#> 3 4.7 3.2 1.3 0.2 setosa
#> 4 4.6 3.1 1.5 0.2 setosa
#> 5 5.0 3.6 1.4 0.2 setosa
Records can also be inserted directly as JSON strings. This requires a character vector where each element is a valid JSON string.
subjects <- mongo("subjects")
str <- c('{"name" : "jerry"}' , '{"name": "anna", "age" : 23}', '{"name": "joe"}')
subjects$insert(str)
#> List of 6
#> $ nInserted : int 3
#> $ nMatched : int 0
#> $ nModified : int 0
#> $ nRemoved : int 0
#> $ nUpserted : int 0
#> $ writeErrors: list()
#> _id name age
#> 1 5b6ca14047a302fe1310fd2e jerry NA
#> 2 5b6ca14047a302fe1310fd2f anna 23
#> 3 5b6ca14047a302fe1310fd30 joe NA
Obviously you can generate such JSON records dynamically from data via e.g. jsonlite::toJSON
.
4.2 Remove
The same syntax that we use in find()
to select records for reading, can also be used to select records for deleting:
#> [1] 150
#> [1] 100
Use the just_one
option to delete a single record:
#> [1] 99
To delete all records in the collection (but not the collection itself):
#> [1] 0
The drop()
operator will delete an entire collection. This includes all data, as well as metadata such as collection indices.
4.3 Update / Upsert
To modify existing records, use the update()
operator:
#> name age
#> 1 jerry NA
#> 2 anna 23
#> 3 joe NA
#> List of 3
#> $ modifiedCount: int 1
#> $ matchedCount : int 1
#> $ upsertedCount: int 0
#> name age
#> 1 jerry 31
#> 2 anna 23
#> 3 joe NA
By default, the update() method updates a single document. To update multiple documents, use the multi option in the update() method.
#> List of 3
#> $ modifiedCount: int 3
#> $ matchedCount : int 3
#> $ upsertedCount: int 0
#> List of 3
#> $ modifiedCount: int 2
#> $ matchedCount : int 2
#> $ upsertedCount: int 0
#> name age has_age
#> 1 jerry 31 TRUE
#> 2 anna 23 TRUE
#> 3 joe NA FALSE
If no document matches the update condition, the default behavior of the update method is to do nothing. By specifying the upsert option to true, the update operation either updates matching document(s) or inserts a new document if no matching document exists.
#> List of 4
#> $ modifiedCount: int 0
#> $ matchedCount : int 0
#> $ upsertedCount: int 1
#> $ upsertedId : chr "5b6ca140368aa2856aaf107b"
#> name age has_age
#> 1 jerry 31 TRUE
#> 2 anna 23 TRUE
#> 3 joe NA FALSE
#> 4 erik 29 NA
4.4 Array Filters
Starting in MongoDB 3.6, when updating an array field, you can specify arrayFilters that determine which array elements to update.
students <- mongo("students")
students$insert(c(
'{ "student" : 1, "grades" : [ 95, 92, 90 ] }',
'{ "student" : 2, "grades" : [ 98, 100, 102 ] }',
'{ "student" : 3, "grades" : [ 95, 110, 100] }'))
#> List of 6
#> $ nInserted : int 3
#> $ nMatched : int 0
#> $ nModified : int 0
#> $ nRemoved : int 0
#> $ nUpserted : int 0
#> $ writeErrors: list()
#> student grades
#> 1 1 95, 92, 90
#> 2 2 98, 100, 102
#> 3 3 95, 110, 100
To modify all elements that are greater than or equal to 100 in the grades
array, use the filtered positional operator $[<identifier>]
in the filters
parameter:
students$update(query = '{}', update = '{"$set":{"grades.$[element]":100}}',
filters = '[{"element": {"$gte":100}}]', multiple = TRUE)
#> List of 3
#> $ modifiedCount: int 2
#> $ matchedCount : int 3
#> $ upsertedCount: int 0
#> student grades
#> 1 1 95, 92, 90
#> 2 2 98, 100, 100
#> 3 3 95, 100, 100