MISE À JOUR :
J'ai fondamentalement mal compris le problème. Felix interrogeait mongoDB pour déterminer combien d'éléments appartenaient à chaque gamme ; par conséquent, mon approche n'a pas fonctionné, car j'essayais de demander à mongoDB pour Les objets. Felix a beaucoup de données, donc c'est complètement déraisonnable.
Félix, voici une fonction mise à jour qui devrait faire ce que vous voulez :
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 est l'"étape" par laquelle il faut regarder en arrière. Par exemple, si nous voulions regarder les 12 dernières heures, je définirais quantum = timedelta(hours=1)
et num = 12
.Un exemple d'utilisation mis à jour où nous obtenons les 30 derniers jours serait :
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 :
D'accord, c'est ma tentative de refactorisation pour vous. Blubber a suggéré d'apprendre JS et MapReduce. Ce n'est pas nécessaire tant que vous suivez ses autres suggestions :créez un index sur le champ de l'heure et réduisez le nombre de requêtes. Ceci est ma meilleure tentative, avec une légère refactorisation. J'ai tout de même un tas de questions et de commentaires.
À partir de :
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
Vous faites une requête mongoDB pour trouver toutes les données de chaque jour des 30 derniers jours. Pourquoi n'utilisez-vous pas une seule requête ? Et une fois que vous avez toutes les données, pourquoi ne pas simplement filtrer les données supprimées ?
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
Je ne sais vraiment pas pourquoi vous faisiez 60 requêtes (30 * 2, une pour toutes les données, une pour les non supprimées). Y a-t-il une raison particulière pour laquelle vous construisez les données au jour le jour ?
Ensuite, vous avez :
x = range(30)
N = len(x)
Pourquoi pas :
N = 30
x = range(N)
len(range(x)
est égal à x
, mais prend du temps à calculer. La façon dont vous l'avez écrit à l'origine est juste un peu... bizarre.
Voici mon point de vue, avec les changements que j'ai suggérés d'une manière aussi générale que possible.
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()