MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Visualizzazione delle statistiche dei dati Mongodb utilizzando matplotlib

AGGIORNAMENTO:

Fondamentalmente ho frainteso il problema. Felix stava interrogando mongoDB per capire quanti elementi rientravano in ciascun intervallo; quindi, il mio approccio non ha funzionato, perché stavo cercando di chiedere a mongoDB per gli oggetti. Felix ha molti dati, quindi è del tutto irragionevole.

Felix, ecco una funzione aggiornata che dovrebbe fare quello che vuoi:

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 è il "passo" da cui guardare indietro. Ad esempio, se volessimo guardare le ultime 12 ore, imposterei quantum = timedelta(hours=1) e num = 12 .Un esempio di utilizzo aggiornato in cui otteniamo gli ultimi 30 giorni sarebbe:

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()  

Originale:

Va bene, questo è il mio tentativo di refactoring per te. Blubber ha suggerito di imparare JS e MapReduce. Non è necessario che tu segua i suoi altri suggerimenti:crea un indice nel campo dell'ora e riduci il numero di query. Questo è il mio miglior tentativo in tal senso, insieme a un leggero refactoring. Ho un sacco di domande e commenti però.

A partire da:

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

Stai effettuando una richiesta mongoDB per trovare tutti i dati di ogni giorno degli ultimi 30 giorni. Perché non usi solo una richiesta? E una volta che hai tutti i dati, perché non filtrare semplicemente i dati eliminati?

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

Non sono davvero sicuro del motivo per cui stavi facendo 60 richieste (30 * 2, una per tutti i dati, una per i non eliminati). C'è qualche motivo particolare per cui hai accumulato i dati giorno per giorno?

Quindi, hai:

x = range(30)
N = len(x)

Perché no:

N = 30
x = range(N)

len(range(x) è uguale a x , ma richiede tempo per il calcolo. Il modo in cui l'hai scritto originariamente è solo un po'... strano.

Ecco la mia prova, con le modifiche che ho suggerito di apportare nel modo più generale possibile.

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()