Lompat ke konten Lompat ke sidebar Lompat ke footer

Penerapan Database MongoDB dengan Visual Studio Code

 

Apa itu MongoDB?

MongoDB merupakan salah satu jenis database NoSQL yang berbasis dokumen. Berbeda dengan database relasional tradisional, MongoDB menggunakan format BSON (Binary JSON) untuk menyimpan data. Keunggulan MongoDB terletak pada kemampuannya menangani data semi-struktural atau tidak terstruktur dengan lebih efisien.

Mengapa MongoDB?

Pertanyaan ini wajar muncul. MongoDB menjadi pilihan populer karena kemudahannya dalam menyimpan data yang beragam, skalabilitas horizontal yang baik, dan fleksibilitas dalam memodelkan data. Penerapan MongoDB seringkali memberikan solusi yang optimal untuk aplikasi yang membutuhkan penanganan data yang cepat dan terdistribusi.

Penerapan
Sebelum masuk ke materi prakter, tentunya kita perlu data untuk diolah, data dapat di cari pada laman web kaggle.com.





Visualisasi & Filter Data, serta fungsi CRUD data.

Langkah - Langkah :

1. Import file datasheet yang akan dipakai ke MongoDB menggunakkan VS Code. pastikan file sudah csv dan nama sesuai dengan nama file. buat file pada VS Code dengan nama film.cvs

berikut kode untuk impor csv :

import csv
from pymongo import MongoClient

client = MongoClient('mongodb://localhost:27017/')
db = client['pbl']
koleksi = db['salary']

# Impor data dari file CSV ke MongoDB
path_csv = 'ds_salaries.csv'

with open(path_csv, 'r') as csvfile:
    csv_reader = csv.DictReader(csvfile)
    for row in csv_reader:
        koleksi.insert_one(row)
    print("Data dari CSV berhasil diimpor ke MongoDB.")


2. Untuk menampilkan data dan fungsi CRUD, buat file app.py lalu isi dengan kode seperti dibawah ini :

from flask import Flask, render_template, request, redirect
from pymongo import MongoClient
from bson import ObjectId
import plotly.graph_objs as go
from plotly.subplots import make_subplots


app = Flask(__name__)
client = MongoClient('mongodb://localhost:27017/')
db = client['pbl']
koleksi = db['salary']

def index():
    data_cursor = koleksi.find()
    formatted_data = []
    header = ['work_year', 'experience_level', 'employment_type', 'job_title', 'salary', 'salary_currency', 'salary_in_usd', 'employee_residence', 'remote_ratio', 'company_location', 'company_size']

    for row in data_cursor:
        formatted_row = {key: row[key] for key in header}
        formatted_data.append(formatted_row)

    return render_template('index.html', data=formatted_data)

# Rute lainnya untuk tambah, edit, dan hapus data

# Rute untuk menampilkan data dan melakukan pencarian
@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        query = request.form.get('query')
        if query:
            data_cursor = koleksi.find({
                '$or': [
                    {'work_year': {'$regex': query, '$options': 'i'}},
                    {'experience_level': {'$regex': query, '$options': 'i'}},
                    {'employment_type': {'$regex': query, '$options': 'i'}},
                    {'job_title': {'$regex': query, '$options': 'i'}},
                    {'salary': {'$regex': query, '$options': 'i'}},
                    {'salary_currency': {'$regex': query, '$options': 'i'}},
                    {'salary_in_usd': {'$regex': query, '$options': 'i'}},
                    {'employee_residence': {'$regex': query, '$options': 'i'}},
                    {'remote_ratio': {'$regex': query, '$options': 'i'}},
                    {'company_location': {'$regex': query, '$options': 'i'}},
                    {'company_size': {'$regex': query, '$options': 'i'}}
                ]
            })
            data_list = list(data_cursor)
            return render_template('index.html', data=data_list)
        else:
            return redirect('/')
    else:
        data_cursor = koleksi.find()
        data_list = list(data_cursor)
        return render_template('index.html', data=data_list)

# Rute untuk menambah data baru
@app.route('/add', methods=['POST'])
def add():
    new_data = {
        'work_year': request.form['work_year'],
        'experience_level': request.form['experience_level'],
        'employment_type': request.form['employment_type'],
        'job_title': request.form['job_title'],
        'salary': request.form['salary'],
        'salary_currency': request.form['salary_currency'],
        'salary_in_usd': request.form['salary_in_usd'],
        'employee_residence': request.form['employee_residence'],
        'remote_ratio': request.form['remote_ratio'],
        'company_location': request.form['company_location'],
        'company_size': request.form['company_size']
    }
    koleksi.insert_one(new_data)
    return redirect('/')

# Rute untuk menghapus data
@app.route('/delete/<id>', methods=['GET'])
def delete(id):
    koleksi.delete_one({'_id': ObjectId(id)})
    return redirect('/')

# Rute untuk menampilkan form edit
@app.route('/edit/<string:row_id>', methods=['GET'])
def edit_data(row_id):
    data = koleksi.find_one({'_id': ObjectId(row_id)})
    if data:
        return render_template('edit.html', data=data)
    else:
        return "Data not found", 404  # Optional: Menampilkan pesan jika data tidak ditemukan


@app.route('/charts')
def charts():
    # Ambil data dari MongoDB
    data_cursor = koleksi.find()
    data_list = list(data_cursor)

    # Siapkan data untuk grafik lingkaran
    salaries = [float(data['salary_in_usd']) for data in data_list]

    # Ambil 10 kategori pertama untuk grafik lingkaran
    top_10_salaries = sorted(data_list, key=lambda x: float(x['salary_in_usd']), reverse=True)[:10]
    salaries = [float(data['salary_in_usd']) for data in top_10_salaries]
    labels = [data['job_title'] for data in top_10_salaries]

    # Buat grafik lingkaran untuk menampilkan distribusi gaji
    fig_pie = go.Figure(data=[go.Pie(labels=labels, values=salaries)])
    fig_pie.update_layout(title="Top 10 Job Salaries")

    # Grafik batang untuk menampilkan rata-rata gaji per tahun bekerja
    work_years = [data['work_year'] for data in data_list]
    unique_work_years = list(set(work_years))
    avg_salaries = [sum([float(data['salary_in_usd']) for data in data_list if data['work_year'] == year])
                    / len([float(data['salary_in_usd']) for data in data_list if data['work_year'] == year])
                    for year in unique_work_years]

    fig_bar = go.Figure(data=go.Bar(x=unique_work_years, y=avg_salaries))
    fig_bar.update_layout(title="Average Salary per Work Year")

    # Grafik garis untuk menampilkan perbandingan gaji berdasarkan tingkat pengalaman
    exp_levels = [data['experience_level'] for data in data_list]
    unique_exp_levels = list(set(exp_levels))
    avg_salaries_exp = [sum([float(data['salary_in_usd']) for data in data_list if data['experience_level'] == level])
                        / len([float(data['salary_in_usd']) for data in data_list if data['experience_level'] == level])
                        for level in unique_exp_levels]

    fig_line = go.Figure(data=go.Scatter(x=unique_exp_levels, y=avg_salaries_exp, mode='lines+markers'))
    fig_line.update_layout(title="Average Salary per Experience Level")

    # Konversi setiap figure ke dalam representasi HTML agar bisa dimasukkan ke dalam template
    graph_html_pie = fig_pie.to_html(full_html=False)
    graph_html_bar = fig_bar.to_html(full_html=False)
    graph_html_line = fig_line.to_html(full_html=False)

    return render_template('charts.html', graph_pie=graph_html_pie, graph_bar=graph_html_bar, graph_line=graph_html_line)


# Rute untuk menyimpan perubahan dari form edit
@app.route('/update/<id>', methods=['POST'])
def update(id):
    updated_data = {
        'work_year': request.form['work_year'],
        'experience_level': request.form['experience_level'],
        'employment_type': request.form['employment_type'],
        'job_title': request.form['job_title'],
        'salary': request.form['salary'],
        'salary_currency': request.form['salary_currency'],
        'salary_in_usd': request.form['salary_in_usd'],
        'employee_residence': request.form['employee_residence'],
        'remote_ratio': request.form['remote_ratio'],
        'company_location': request.form['company_location'],
        'company_size': request.form['company_size']
    }
    koleksi.update_one({'_id': ObjectId(id)}, {'$set': updated_data})
    return redirect('/')

if __name__ == '__main__':
    app.run(debug=True)

3. Untuk menampilkan grafik, buat Buatlah folder baru "templates" untuk menyimpan script html, terdapat 3 file yaitu index.html untuk mengatur tampilan halaman awal, edit.html untuk mengatur tampilan halaman edit, dan charts.html untuk mengatur tampilan halaman grafik.

  • Kode file index.html :
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Data Gaji Karyawan</title>
    <style>
      table {
        border-collapse: collapse;
        width: 100%;
      }

      th,
      td {
        border: 1px solid black;
        padding: 8px;
        text-align: center;
        max-width: 200px; /* Atur lebar maksimum untuk kolom */
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        margin: 4px; /* Menambahkan jarak pada setiap sisi */
      }

      th:nth-child(1),
      td:nth-child(1) {
        width: 8%; /* Atur lebar kolom work_year di sini */
      }

      th:nth-child(2),
      td:nth-child(2) {
        width: 8%; /* Atur lebar kolom experience_level di sini */
      }

      th:nth-child(3),
      td:nth-child(3) {
        width: 8%; /* Atur lebar kolom employment_type di sini */
      }

      th:nth-child(4),
      td:nth-child(4) {
        width: 16%; /* Atur lebar kolom job_title di sini */
      }

      th:nth-child(5),
      td:nth-child(5) {
        width: 8%; /* Atur lebar kolom salary di sini */
      }

      th:nth-child(6),
      td:nth-child(6) {
        width: 12%; /* Atur lebar kolom salary_currency di sini */
      }

      th:nth-child(7),
      td:nth-child(7) {
        width: 12%; /* Atur lebar kolom salary_in_usd di sini */
      }

      th:nth-child(8),
      td:nth-child(8) {
        width: 12%; /* Atur lebar kolom employee_residence di sini */
      }

      th:nth-child(9),
      td:nth-child(9) {
        width: 8%; /* Atur lebar kolom remote_ratio di sini */
      }

      th:nth-child(10),
      td:nth-child(10) {
        width: 12%; /* Atur lebar kolom company_location di sini */
      }

      th:nth-child(11),
      td:nth-child(11) {
        width: 8%; /* Atur lebar kolom company_size di sini */
      }

      /* Tambahkan margin-bottom untuk memberikan ruang antara form dan tabel */
      form {
        margin-bottom: 20px;
      }
    </style>
  </head>
  <body>
    <h1>Data Gaji Karyawan</h1>
    <p>Data Length: {{ data|length }}</p>
    <form action="/" method="POST">
      <!-- <label for="search">Cari:</label> -->
      <input type="text" id="search" name="query" />
      <button type="submit">Cari</button>
    </form>

    <button
      type="button"
      onclick="window.location.href='/charts'"
      style="width: 150px; height: 25px; margin-top: 10px; margin-bottom: 10px"
    >
      Tampilkan Grafik
    </button>

    <form
      action="/add"
      method="POST"
      style="display: grid; grid-template-columns: 140px 200px; gap: 10px"
    >
      <label for="work_year" style="text-align: right">Work Year:</label>
      <input type="text" id="work_year" name="work_year" />

      <label for="experience_level" style="text-align: right"
        >Experience Level:</label
      >
      <input type="text" id="experience_level" name="experience_level" />

      <label for="employment_type" style="text-align: right"
        >Employment Type:</label
      >
      <input type="text" id="employment_type" name="employment_type" />

      <label for="job_title" style="text-align: right">Job Title:</label>
      <input type="text" id="job_title" name="job_title" />

      <label for="salary" style="text-align: right">Salary:</label>
      <input type="text" id="salary" name="salary" />

      <label for="salary_currency" style="text-align: right"
        >Salary Currency:</label
      >
      <input type="text" id="salary_currency" name="salary_currency" />

      <label for="salary_in_usd" style="text-align: right"
        >Salary in USD:</label
      >
      <input type="text" id="salary_in_usd" name="salary_in_usd" />

      <label for="employee_residence" style="text-align: right"
        >Employee Residence:</label
      >
      <input type="text" id="employee_residence" name="employee_residence" />

      <label for="remote_ratio" style="text-align: right">Remote Ratio:</label>
      <input type="text" id="remote_ratio" name="remote_ratio" />

      <label for="company_location" style="text-align: right"
        >Company Location:</label
      >
      <input type="text" id="company_location" name="company_location" />

      <label for="company_size" style="text-align: right">Company Size:</label>
      <input type="text" id="company_size" name="company_size" />

      <button type="submit" style="grid-column: span 2; justify-self: end">
        Tambah Data
      </button>
    </form>

    <table>
      <thead>
        <tr>
          <th>Work Year</th>
          <th>Experience Level</th>
          <th>Employment Type</th>
          <th>Job Title</th>
          <th>Salary</th>
          <th>Salary Currency</th>
          <th>Salary in USD</th>
          <th>Employee Residence</th>
          <th>Remote Ratio</th>
          <th>Company Location</th>
          <th>Company Size</th>
          <th>Aksi</th>
        </tr>
      </thead>
      <tbody>
        {% for row in data %}
        <tr>
          <td>{{ row.work_year }}</td>
          <td>{{ row.experience_level }}</td>
          <td>{{ row.employment_type }}</td>
          <td>{{ row.job_title }}</td>
          <td>{{ row.salary }}</td>
          <td>{{ row.salary_currency }}</td>
          <td>{{ row.salary_in_usd }}</td>
          <td>{{ row.employee_residence }}</td>
          <td>{{ row.remote_ratio }}</td>
          <td>{{ row.company_location }}</td>
          <td>{{ row.company_size }}</td>
          <td>
            <form action="/edit/{{ row._id }}" method="GET">
              <button type="submit">Edit Data</button>
            </form>
            <form action="/delete/{{ row._id }}" method="GET">
              <button type="submit">Hapus</button>
            </form>
          </td>
        </tr>
        {% endfor %}
      </tbody>
    </table>
  </body>
</html>


  • Kode file edit.html 
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Edit Data</title>
    <style>
      /* Atur gaya sesuai kebutuhan Anda */
    </style>
  </head>
  <body>
    <h1>Edit Data</h1>
    <form
      action="/update/{{ data._id }}"
      method="POST"
      style="display: grid; grid-template-columns: 140px 200px; gap: 10px"
    >
      <label for="work_year" style="text-align: right">Work Year:</label>
      <input
        type="text"
        id="work_year"
        name="work_year"
        value="{{ data.work_year }}"
      />
      <label for="experience_level" style="text-align: right"
        >Experience Level:</label
      >
      <input
        type="text"
        id="experience_level"
        name="experience_level"
        value="{{ data.experience_level }}"
      />
      <label for="employment_type" style="text-align: right"
        >Employment Type:</label
      >
      <input
        type="text"
        id="employment_type"
        name="employment_type"
        value="{{ data.employment_type }}"
      />
      <label for="job_title" style="text-align: right">Job Title:</label>
      <input
        type="text"
        id="job_title"
        name="job_title"
        value="{{ data.job_title }}"
      />
      <label for="salary" style="text-align: right">Salary:</label>
      <input type="text" id="salary" name="salary" value="{{ data.salary }}" />
      <label for="salary_currency" style="text-align: right"
        >Salary Currency:</label
      >
      <input
        type="text"
        id="salary_currency"
        name="salary_currency"
        value="{{ data.salary_currency }}"
      />
      <label for="salary_in_usd" style="text-align: right"
        >Salary in USD:</label
      >
      <input
        type="text"
        id="salary_in_usd"
        name="salary_in_usd"
        value="{{ data.salary_in_usd }}"
      />
      <label for="employee_residence" style="text-align: right"
        >Employee Residence:</label
      >
      <input
        type="text"
        id="employee_residence"
        name="employee_residence"
        value="{{ data.employee_residence }}"
      />
      <label for="remote_ratio" style="text-align: right">Remote Ratio:</label>
      <input
        type="text"
        id="remote_ratio"
        name="remote_ratio"
        value="{{ data.remote_ratio }}"
      />
      <label for="company_location" style="text-align: right"
        >Company Location:</label
      >
      <input
        type="text"
        id="company_location"
        name="company_location"
        value="{{ data.company_location }}"
      />
      <label for="company_size" style="text-align: right">Company Size:</label>
      <input
        type="text"
        id="company_size"
        name="company_size"
        value="{{ data.company_size }}"
      />
      <button type="submit" style="grid-column: span 2; justify-self: end">
        Update Data
      </button>
    </form>
  </body>
</html>


  • Kode file charts.html :
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Charts</title>
    <!-- Plotly.js -->
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
  </head>
  <body>
    <div id="chart1">
      <!-- Ini adalah tempat untuk grafik lingkaran -->
      {{ graph_pie|safe }}
    </div>
    <div id="chart2">
      <!-- Ini adalah tempat untuk grafik batang -->
      {{ graph_bar|safe }}
    </div>
    <div id="chart3">
      <!-- Ini adalah tempat untuk grafik garis -->
      {{ graph_line|safe }}
    </div>
  </body>
</html>


HASIL :

1. Tampilan Awal 

Pada halaman awal akan muncul data yang sudah diimport dan jumlah datanya. Di sini juga terdapat tools untuk melakukan pencarian berdasarkan kategori tertentu, tampilkan grafik, tambah data, hapus data, dan edit data pada pojok kanan tabel (aksi).



2. Tampilan edit data

apabila tombol aksi dikil pada edit, maka akan muncul halaman edit data


3. Hasil tampilan cari berdasarkan kategori

apabila ingin melihat data tertentu saja, kita hanya perlu ketikkan sesuai dengan kategorinya, misal ingin melihat data gaji kategori ,  maka ketik pada pencarian :

- Data tahun "2002"





hasilnya muncul data seperti berikut:

- Data pekerja "applied scientist"





hasilnya muncul data seperti berikut:



- Data gaji "175000" USD







hasilnya muncul data seperti berikut:



4. Tampilan Grafik berdasarkan kategori :

- Berdasarkan Top 10 Gaji Karyawan



- Berdasarkan Gaji Rata-Rata per Tahun



- Berdasarkan Rata-Rata Gaji per Tingkat Pengalaman



NT: setiap grafik terdapat menu download as png, zoom in, zoom out, dll pada pojok kanan atas




Posting Komentar untuk "Penerapan Database MongoDB dengan Visual Studio Code"