mongolite:
MongoDB Client for R




Alfa Nugraha Pradana

Prodi Statistika dan Sains Data IPB University

Outline


  • Aggregation Operations

    • Aggregation Pipeline
    • Map-Reduce
  • mongolite

  • R + Atlas + Twitter Apps

  • GitHub Actions

Aggregation Operations

Aggregation Operations


Operasi aggregation adalah sebuah operasi dimana kumpulan dokumen pada koleksi diproses dengan satu atau beberapa perintah di dalam suatu stages atau tahapan tertentu sehingga dapat mengeluarkan hasil olah data yang dibutuhkan. Beberapa kegunaan operasi ini:

  • Mengelompokkan nilai dari beberapa dokumen
  • Melakukan operasi pada suatu kelompok data agar menghasilkan nilai tunggal seperti nilai total, dan sebagainya
  • Menganalisis perubahan data dari waktu ke waktu

Cara Untuk menggunakan operasi aggregation:

Aggregation Pipeline


  • Suatu Aggregation Pipeline terdiri dari satu atau lebih stages dalam memproses dokumen
  • Setiap tahapan dapat berupa operasi misalnya seleksi dokumen, pengelompokan dokumen, dan menghitung nilai tertentu dari dokumen tersebut seperti nilai total, rata-rata, nilai maksimum, dan minimum
  • Perintah yang digunakan db.<collection>.aggregate()


Aggregation Pipeline Stages


Beberapa perintah stages yang biasa digunakan:

Operator Keterangan
$match Memilih dokumen yang sesuai dengan kriteria yang diinginkan
$group Mengelompokan dokumen berdasarkan identifier expression yang diberikan
$project Membentuk kembali dokumen, seperti menambahkan field baru dan lainnya
$sort Mengurutkan dokumen berdasarkan key yang diberikan
$count Menghitung jumlah dokumennakan text
$limit Memilih n dokumen pertama untuk digunakan pada pipline
$skip Melewatkan n dokumen pertama dan sisa dokumen lainnya digunakan
$lookup Melakukan left outer join kepada koleksi lain pada database yang sama
$out Mengubah dokumen output dari aggregation pipeline menjadi koleksi

Stage 1: $match


db.cities.aggregate([
  { $match : {  continent: {$in: ["Asia", "Africa"]} }}
])
                        _id      name     country continent population
1  646c01c1bbd6335311b9017e     Seoul South Korea      Asia     25.674
2  646c01c1bbd6335311b9017f    Mumbai       India      Asia     19.980
3  646c01c1bbd6335311b90180     Lagos     Nigeria    Africa     13.463
4  646c01c1bbd6335311b90181   Beijing       China      Asia     19.618
5  646c01c1bbd6335311b90182  Shanghai       China      Asia     25.582
6  646c01c1bbd6335311b90183     Osaka       Japan      Asia     19.281
7  646c01c1bbd6335311b90184     Cairo       Egypt    Africa     20.076
8  646c01c1bbd6335311b90185     Tokyo       Japan      Asia     37.400
9  646c01c1bbd6335311b90186   Karachi    Pakistan      Asia     15.400
10 646c01c1bbd6335311b90187     Dhaka  Bangladesh      Asia     19.578
11 646c01c1bbd6335311b9018b     Delhi       India      Asia     28.514
12 646c01c1bbd6335311b9018d   Kolkata       India      Asia     14.681
13 646c01c1bbd6335311b9018f    Manila Philippines      Asia     13.482
14 646c01c1bbd6335311b90190 Chongqing       China      Asia     14.838

Stage 2: $sort


db.cities.aggregate([ 
  {$match : {  continent: {$in: ["Asia", "Africa"]} }},
  {$sort: { population: -1  }}
])
                        _id      name     country continent population
1  646c01c1bbd6335311b90185     Tokyo       Japan      Asia     37.400
2  646c01c1bbd6335311b9018b     Delhi       India      Asia     28.514
3  646c01c1bbd6335311b9017e     Seoul South Korea      Asia     25.674
4  646c01c1bbd6335311b90182  Shanghai       China      Asia     25.582
5  646c01c1bbd6335311b90184     Cairo       Egypt    Africa     20.076
6  646c01c1bbd6335311b9017f    Mumbai       India      Asia     19.980
7  646c01c1bbd6335311b90181   Beijing       China      Asia     19.618
8  646c01c1bbd6335311b90187     Dhaka  Bangladesh      Asia     19.578
9  646c01c1bbd6335311b90183     Osaka       Japan      Asia     19.281
10 646c01c1bbd6335311b90186   Karachi    Pakistan      Asia     15.400
11 646c01c1bbd6335311b90190 Chongqing       China      Asia     14.838
12 646c01c1bbd6335311b9018d   Kolkata       India      Asia     14.681
13 646c01c1bbd6335311b9018f    Manila Philippines      Asia     13.482
14 646c01c1bbd6335311b90180     Lagos     Nigeria    Africa     13.463

$group & $sort


db.cities.aggregate([ 
  {$group: {
      _id: {"continent": "$continent"},
      total_population: {$sum: "$population"}
    }
  },
  {$sort: {total_population: -1 }}
])
      continent total_population
1          Asia          254.028
2 South America           49.910
3 North America           40.400
4        Africa           33.539
5        Europe           14.751

$project

db.cities.aggregate([{
    $project: {
      "_id": 0,
      "location": { "country": "$country", "continent": "$continent" },
      "name": "$name",
      "population": "$population"
    }
}])
   lokasi.negara  lokasi.benua           kota populasi
1    South Korea          Asia          Seoul   25.674
2          India          Asia         Mumbai   19.980
3        Nigeria        Africa          Lagos   13.463
4          China          Asia        Beijing   19.618
5          China          Asia       Shanghai   25.582
6          Japan          Asia          Osaka   19.281
7          Egypt        Africa          Cairo   20.076
8          Japan          Asia          Tokyo   37.400
9       Pakistan          Asia        Karachi   15.400
10    Bangladesh          Asia          Dhaka   19.578
11        Brazil South America Rio de Janeiro   13.293
12        Brazil South America      São Paulo   21.650
13        Mexico North America    Mexico City   21.581
14         India          Asia          Delhi   28.514
15     Argentina South America   Buenos Aires   14.967
16         India          Asia        Kolkata   14.681
17 United States North America       New York   18.819
18   Philippines          Asia         Manila   13.482
19         China          Asia      Chongqing   14.838
20        Turkey        Europe       Istanbul   14.751

Menyatukan semua stages

db.cities.aggregate([
  { $match: { "continent": { $in: ["North America", "Asia"] }} },
  { $sort: { "population": -1 }},
  {
      $group: {
        "_id": { "continent": "$continent", "country": "$country" },
        "first_city": { $first: "$name" },
        "highest_population": { $max: "$population" }
      }
  },
  { $match: { "highest_population": { $gt: 20.0 }}},
  { $sort: { "highest_population": -1 }},
  {
    $project: {
      "_id": 0,
      "location": { "country": "$_id.country", "continent": "$_id.continent" },
      "most_populated_city": { "name": "$first_city", "population": "$highest_population"}
    }
  }
])
  lokasi.negara  lokasi.benua kota_terpadat.nama_kota kota_terpadat.populasi
1         Japan          Asia                   Tokyo                 37.400
2         India          Asia                   Delhi                 28.514
3   South Korea          Asia                   Seoul                 25.674
4         China          Asia                Shanghai                 25.582
5        Mexico North America             Mexico City                 21.581

Single Purpose Aggregation Methods

  • Melakukan agregasi beberapa dokumen dalam satu collection
  • Sederhana tetapi tidak memiliki kemampuan seperti Aggregation Pipeline

Contoh single purpose aggregation method :

Perintah Keterangan
db.<collection>.estimatedDocumentCount() Menghasilkan perkiraan jumlah dokumen pada suatu koleksi
db.<collection>.count() Menghasilkan jumlah dokumen pada suatu koleksi
db.<collection>.distinct() Menghasilkan nilai unik dari kolom spesifik dalam array

Map-Reduce

Map-Reduce


  • Mulai dari versi 5.0, fitur ini sudah tidak digunakan kembali
  • Aggregation Pipeline dianggap memberikan kinerja dan penggunaan yang lebih baik
  • Operasi Map-Reduce saat ini dapat disubstitusi dengan aggregation pipeline stages seperti $group, $merge, dan lainnya
  • Untuk kustomisasi fungsi Map-Reduce dapat menggunakan operator aggregation $accumulator dan $function

Berbagai contoh alternatif penggunaan Aggregation Pipeline sebagai pengganti dari Map-Reduce dapat dipelajari pada laman berikut:

mongolite


library(mongolite)

# nama koleksi
collection <- "cities"

# nama database
db <- "prak12"

# koneksi ke mongoDB
url <- "mongodb://localhost:27017/"

cities <- mongo(collection=collection, db=db, url=url)

Perintah find()

cities$find()
             name       country     continent population
1           Seoul   South Korea          Asia     25.674
2          Mumbai         India          Asia     19.980
3           Lagos       Nigeria        Africa     13.463
4         Beijing         China          Asia     19.618
5        Shanghai         China          Asia     25.582
6           Osaka         Japan          Asia     19.281
7           Cairo         Egypt        Africa     20.076
8           Tokyo         Japan          Asia     37.400
9         Karachi      Pakistan          Asia     15.400
10          Dhaka    Bangladesh          Asia     19.578
11 Rio de Janeiro        Brazil South America     13.293
12      São Paulo        Brazil South America     21.650
13    Mexico City        Mexico North America     21.581
14          Delhi         India          Asia     28.514
15   Buenos Aires     Argentina South America     14.967
16        Kolkata         India          Asia     14.681
17       New York United States North America     18.819
18         Manila   Philippines          Asia     13.482
19      Chongqing         China          Asia     14.838
20       Istanbul        Turkey        Europe     14.751

Perintah aggregate()

cities$aggregate('[{"$match": {  "continent": {"$in": ["Asia", "Africa"]} }}]')
                        _id      name     country continent population
1  646c01c1bbd6335311b9017e     Seoul South Korea      Asia     25.674
2  646c01c1bbd6335311b9017f    Mumbai       India      Asia     19.980
3  646c01c1bbd6335311b90180     Lagos     Nigeria    Africa     13.463
4  646c01c1bbd6335311b90181   Beijing       China      Asia     19.618
5  646c01c1bbd6335311b90182  Shanghai       China      Asia     25.582
6  646c01c1bbd6335311b90183     Osaka       Japan      Asia     19.281
7  646c01c1bbd6335311b90184     Cairo       Egypt    Africa     20.076
8  646c01c1bbd6335311b90185     Tokyo       Japan      Asia     37.400
9  646c01c1bbd6335311b90186   Karachi    Pakistan      Asia     15.400
10 646c01c1bbd6335311b90187     Dhaka  Bangladesh      Asia     19.578
11 646c01c1bbd6335311b9018b     Delhi       India      Asia     28.514
12 646c01c1bbd6335311b9018d   Kolkata       India      Asia     14.681
13 646c01c1bbd6335311b9018f    Manila Philippines      Asia     13.482
14 646c01c1bbd6335311b90190 Chongqing       China      Asia     14.838

Perintah aggregate() dengan menggunakan beberapa stages

cities$aggregate('[
  { "$match": { "continent": { "$in": ["North America", "Asia"] }} },
  { "$sort": { "population": -1 }},
  {
    "$group": {
      "_id": { "continent": "$continent", "country": "$country" },
      "first_city": { "$first": "$name" },
      "highest_population": { "$max": "$population" }
    }
  },
  { "$match": { "highest_population": { "$gt": 20.0 }}},
  { "$sort": { "highest_population": -1 }},
  {
    "$project": {
      "_id": 0,
      "lokasi": { "negara": "$_id.country", "benua": "$_id.continent" },
      "kota_terpadat": { "nama_kota": "$first_city", "populasi": "$highest_population"}
    }
  }                 
]')
  lokasi.negara  lokasi.benua kota_terpadat.nama_kota kota_terpadat.populasi
1         Japan          Asia                   Tokyo                 37.400
2         India          Asia                   Delhi                 28.514
3   South Korea          Asia                   Seoul                 25.674
4         China          Asia                Shanghai                 25.582
5        Mexico North America             Mexico City                 21.581

R + Atlas + Twitter Apps


Menggunakan paket mongolite & rtweet


Membangun koneksi ke Atlas

onepiece_conn <- mongo(
  collection = Sys.getenv("ATLAS_CLOUD_COLLECTION"),
  db         = Sys.getenv("ATLAS_CLOUD_DB"), 
  url        = Sys.getenv("ATLAS_CLOUD_URL")
)


Menggunakan Twitter API untuk koneksi ke aplikasi robot

token <- create_token(
  app = Sys.getenv("TWITTER_APPS"),
  consumer_key    = Sys.getenv("TWITTER_CONSUMER_API_KEY"),
  consumer_secret = Sys.getenv("TWITTER_CONSUMER_API_SECRET"),
  access_token    = Sys.getenv("TWITTER_ACCESS_TOKEN"),
  access_secret   = Sys.getenv("TWITTER_ACCESS_TOKEN_SECRET")
)

Contoh Aplikasi Bot

Membangun koneksi ke MongoDB dan mengatur pesan Twitter

library(rtweet)
library(mongolite)

collection <- "cities"
db <- "prak12"
url <- "mongodb://localhost:27017/"
cities <- mongo(
  collection=collection, 
  db=db, 
  url=url
)

# menyimpan data dari mongoDB ke dataframe
kota <- cities$find()

## membuat hash tag
hashtag <- c("MDS","mongoDB","populasi")

## pesan twitter
status_details <- paste0(
  "Populasi kota ", kota$name[1], " di ", kota$country[1], " adalah ", kota$population[1], " juta jiwa",  
  "\n\n",
  paste0("#", hashtag, collapse = " ")
)


Membuat token dan posting twitter (1)

## set twitter token
## cara 1
token <- create_token(
  app = "onepieceMD",
  consumer_key = Sys.getenv("TWITTER_CONSUMER_API_KEY"),
  consumer_secret = Sys.getenv("TWITTER_CONSUMER_API_SECRET"),
  access_token = Sys.getenv("TWITTER_ACCESS_TOKEN"),
  access_secret = Sys.getenv("TWITTER_ACCESS_TOKEN_SECRET")
)

## posting
post_tweet(
  status = status_details,
  token = token
)


Membuat token dan posting twitter (2)

## cara 2
auth <- rtweet_app()
auth_save(auth, "twitter-auth")

bot <- rtweet_bot(
  api_key = Sys.getenv("TWITTER_CONSUMER_API_KEY"),
  api_secret = Sys.getenv("TWITTER_CONSUMER_API_SECRET"),
  access_token = Sys.getenv("TWITTER_ACCESS_TOKEN"),
  access_secret = Sys.getenv("TWITTER_ACCESS_TOKEN_SECRET")
)

## posting
post_tweet(
  status = status_details,
  token = bot
)

GitHub Actions

Pertanyaan?