UPPDATERING:
Jag har i grunden missuppfattat problemet. Felix frågade mongoDB för att ta reda på hur många föremål som föll i varje sortiment; därför fungerade inte mitt tillvägagångssätt, eftersom jag försökte fråga mongoDB om föremålen. Felix har mycket data, så detta är helt orimligt.
Felix, här är en uppdaterad funktion som ska göra vad du vill:
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 är "steget" att se tillbaka efter. Om vi till exempel ville titta på de senaste 12 timmarna skulle jag ställa in quantum = timedelta(hours=1)
och num = 12
.Ett uppdaterat exempel på användning där vi får de senaste 30 dagarna skulle vara:
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:
Okej, det här är mitt försök att återskapa för dig. Blubber har föreslagit att lära sig JS och MapReduce. Det finns inget behov så länge du följer hans andra förslag:skapa ett index i tidsfältet och minska antalet frågor. Det här är mitt bästa försök med det, tillsammans med en liten refaktorering. Jag har dock en massa frågor och kommentarer.
Börjar 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 gör en mongoDB-förfrågan för att hitta all data från varje dag från de senaste 30 dagarna. Varför använder du inte bara en begäran? Och när du väl har all data, varför inte bara filtrera bort den raderade informationen?
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
Jag är verkligen inte säker på varför du gjorde 60 förfrågningar (30 * 2, en för alla data, en för icke-raderade). Finns det någon speciell anledning till att du byggde upp data dag för dag?
Sedan har du:
x = range(30)
N = len(x)
Varför inte:
N = 30
x = range(N)
len(range(x)
är lika med x
, men tar tid att beräkna. Sättet du skrev det på är bara lite... konstigt.
Här är min känsla för det, med de ändringar jag har föreslagit görs på ett sätt som är så allmänt som möjligt.
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()