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.

#> 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.

#> 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:

#> 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