UPDATE:
Ik heb het probleem fundamenteel verkeerd begrepen. Felix vroeg mongoDB om erachter te komen hoeveel items in elk bereik vielen; daarom werkte mijn aanpak niet, omdat ik mongoDB probeerde te vragen om de artikelen. Felix heeft veel gegevens, dus dit is volkomen onredelijk.
Felix, hier is een bijgewerkte functie die zou moeten doen wat je wilt:
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 is de "stap" om op terug te kijken. Als we bijvoorbeeld naar de laatste 12 uur wilden kijken, zou ik quantum = timedelta(hours=1)
instellen en num = 12
.Een bijgewerkt voorbeeldgebruik waar we de laatste 30 dagen krijgen, zou zijn:
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()
Origineel:
Oké, dit is mijn poging tot refactoring voor jou. Blubber heeft voorgesteld om JS en MapReduce te leren. Het is niet nodig zolang je zijn andere suggesties volgt:maak een index op het tijdveld en verminder het aantal zoekopdrachten. Dit is mijn beste poging daartoe, samen met een kleine aanpassing. Ik heb echter een heleboel vragen en opmerkingen.
Beginnend in:
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
U doet een MongoDB-verzoek om alle gegevens van elke dag van de afgelopen 30 dagen te vinden. Waarom gebruik je niet gewoon één verzoek? En als u eenmaal alle gegevens heeft, waarom filtert u dan niet gewoon de verwijderde gegevens?
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
Ik weet echt niet waarom je 60 verzoeken deed (30 * 2, één voor alle gegevens, één voor niet-verwijderde). Is er een specifieke reden waarom u de gegevens dag na dag hebt opgebouwd?
Dan heb je:
x = range(30)
N = len(x)
Waarom niet:
N = 30
x = range(N)
len(range(x)
is gelijk aan x
, maar kost tijd om te berekenen. De manier waarop je het oorspronkelijk schreef is gewoon een beetje... raar.
Hier is mijn trucje, met de wijzigingen die ik heb voorgesteld, gemaakt op een manier die zo algemeen mogelijk is.
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()