OPDATERING:
Jeg har grundlæggende misforstået problemet. Felix forespurgte mongoDB for at finde ud af, hvor mange varer der faldt ind i hvert område; derfor virkede min tilgang ikke, fordi jeg prøvede at spørge mongoDB om genstandene. Felix har en masse data, så det er helt urimeligt.
Felix, her er en opdateret funktion, som skal gøre, hvad du vil:
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 er "trinnet" at se tilbage efter. For eksempel, hvis vi ville se på de sidste 12 timer, ville jeg indstille quantum = timedelta(hours=1)
og num = 12
.Et opdateret eksempel på brug, hvor vi får de sidste 30 dage, ville være:
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()
Original:
Okay, dette er mit forsøg på at refaktorere for dig. Blubber har foreslået at lære JS og MapReduce. Det er ikke nødvendigt, så længe du følger hans andre forslag:opret et indeks på tidsfeltet, og reducer antallet af forespørgsler. Dette er mit bedste forsøg på det, sammen med en lille refaktorering. Jeg har dog en masse spørgsmål og kommentarer.
Starter om:
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
Du laver en mongoDB-anmodning om at finde alle data fra hver dag fra de seneste 30 dage. Hvorfor bruger du ikke bare én anmodning? Og når du først har alle dataene, hvorfor så ikke bare filtrere de slettede data fra?
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
Jeg er virkelig ikke sikker på, hvorfor du lavede 60 anmodninger (30 * 2, en for alle data, en for ikke-slettet). Er der nogen særlig grund til, at du har opbygget dataene dag for dag?
Så har du:
x = range(30)
N = len(x)
Hvorfor ikke:
N = 30
x = range(N)
len(range(x)
er lig med x
, men tager tid at beregne. Den måde, du skrev det oprindeligt på, er bare lidt... underlig.
Her er mit bud på det, med de ændringer, jeg har foreslået lavet på en måde, der er så generel som muligt.
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()