PERBARUI:
Saya pada dasarnya salah memahami masalahnya. Felix menanyakan mongoDB untuk mencari tahu berapa banyak item yang termasuk dalam setiap rentang; oleh karena itu, pendekatan saya tidak berhasil, karena saya mencoba meminta mongoDB untuk barang-barang. Felix memiliki banyak data, jadi ini sama sekali tidak masuk akal.
Felix, inilah fungsi yang diperbarui yang seharusnya melakukan apa yang Anda inginkan:
def getDataFromLast(num, quantum):
m = my_mongodb()
all = []
not_deleted = []
today = datetime.combine(date.today(), time())
for i in range(num+1)[-1]: # start from oldest
day = today - i*quantum
time_query = {"$gte":day, "$lt": day+quantum}
all.extend(m.data.find({"time":time_query}).count())
not_deleted.extend(m.data.find({"deleted":0, "time":time_query}).count())
return all, not_deleted
Quantum adalah "langkah" untuk melihat ke belakang. Misalnya, jika kita ingin melihat 12 jam terakhir, saya akan menyetel quantum = timedelta(hours=1)
dan num = 12
.Contoh penggunaan yang diperbarui di mana kami mendapatkan 30 hari terakhir adalah:
from datetime import datetime, date, time, timedelta
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from my_conn import my_mongodb
#def getDataFromLast(num, quantum) as defined above
def format_date(x, N, pos=None):
""" This is your format_date function. It now takes N
(I still don't really understand what it is, though)
as an argument instead of assuming that it's a global."""
day = date.today() - timedelta(days=N-x-1)
return day.strftime('%m%d')
def plotBar(data, color):
plt.bar(range(len(data)), data, align='center', color=color)
N = 30 # define the range that we want to look at
all, valid = getDataFromLast(N, timedelta(days=1)) # get the data
plotBar(all, "#4788d2") # plot both deleted and non-deleted data
plotBar(valid, "#0c3688") # plot only the valid data
plt.xticks(range(N), [format_date(i) for i in range(N)], size='small', rotation=30)
plt.grid(axis="y")
plt.show()
Asli:
Baiklah, ini adalah upaya saya untuk refactoring untuk Anda. Blubber menyarankan untuk mempelajari JS dan MapReduce. Tidak perlu selama Anda mengikuti sarannya yang lain:buat indeks di bidang waktu, dan kurangi jumlah kueri. Ini adalah upaya terbaik saya untuk itu, bersama dengan sedikit refactoring. Saya punya banyak pertanyaan dan komentar.
Mulai dari:
with my_mongodb() as m:
for i in range(30):
day = today - timedelta(days = i)
t1 = [m.data.find({"time": {"$gte": day, "$lt": day + timedelta(days = 1)}}).count()] + t1
t2 = [m.data.find({"deleted": 0, "time": {"$gte": day, "$lt": day + timedelta(days = 1)}}).count()] + t2
Anda membuat permintaan mongoDB untuk menemukan semua data dari setiap hari dari 30 hari terakhir. Mengapa Anda tidak menggunakan satu permintaan saja? Dan setelah Anda memiliki semua data, mengapa tidak memfilter data yang dihapus saja?
with my_mongodb() as m:
today = date.today() # not sure why you were combining this with time(). It's the datetime representation of the current time.time()
start_date = today -timedelta(days=30)
t1 = m.find({"time": {"$gte":start_date}}) # all data since start_date (30 days ago)
t2 = filter(lambda x: x['deleted'] == 0, all_data) # all data since start_date that isn't deleted
Saya benar-benar tidak yakin mengapa Anda membuat 60 permintaan (30 * 2, satu untuk semua data, satu untuk tidak dihapus). Apakah ada alasan khusus Anda mengumpulkan data dari hari ke hari?
Maka, Anda memiliki:
x = range(30)
N = len(x)
Mengapa tidak:
N = 30
x = range(N)
len(range(x)
sama dengan x
, tetapi membutuhkan waktu untuk menghitung. Cara Anda menulis awalnya hanya sedikit... aneh.
Inilah celah saya, dengan perubahan yang saya sarankan dibuat dengan cara yang seumum mungkin.
from datetime import datetime, date, time, timedelta
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from my_conn import my_mongodb
def getDataFromLast(delta):
""" Delta is a timedelta for however long ago you want to look
back. For instance, to find everything within the last month,
delta should = timedelta(days=30). Last hour? timedelta(hours=1)."""
m = my_mongodb() # what exactly is this? hopefully I'm using it correctly.
today = date.today() # was there a reason you didn't use this originally?
start_date = today - delta
all_data = m.data.find({"time": {"$gte": start_date}})
valid_data = filter(lambda x: x['deleted'] == 0, all) # all data that isn't deleted
return all_data, valid_data
def format_date(x, N, pos=None):
""" This is your format_date function. It now takes N
(I still don't really understand what it is, though)
as an argument instead of assuming that it's a global."""
day = date.today() - timedelta(days=N-x-1)
return day.strftime('%m%d')
def plotBar(data, color):
plt.bar(range(len(data)), data, align='center', color=color)
N = 30 # define the range that we want to look at
all, valid = getDataFromLast(timedelta(days=N))
plotBar(all, "#4788d2") # plot both deleted and non-deleted data
plotBar(valid, "#0c3688") # plot only the valid data
plt.xticks(range(N), [format_date(i) for i in range(N)], size='small', rotation=30)
plt.grid(axis="y")
plt.show()