MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Mongodb-Datenstatistikvisualisierung mit Matplotlib

AKTUALISIERUNG:

Ich habe das Problem grundsätzlich falsch verstanden. Felix hat mongoDB abgefragt, um herauszufinden, wie viele Elemente in jeden Bereich fallen; Daher hat mein Ansatz nicht funktioniert, weil ich versucht habe, MongoDB nach zu fragen die Gegenstände. Felix hat viele Daten, also ist das völlig unvernünftig.

Felix, hier ist eine aktualisierte Funktion, die tun sollte, was du willst:

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 ist der "Schritt", um zurückzublicken. Wenn wir uns zum Beispiel die letzten 12 Stunden ansehen wollten, würde ich quantum = timedelta(hours=1) setzen und num = 12 .Ein aktualisiertes Verwendungsbeispiel, bei dem wir die letzten 30 Tage erhalten, wä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:

In Ordnung, das ist mein Refactoring-Versuch für Sie. Blubber hat vorgeschlagen, JS und MapReduce zu lernen. Das ist nicht nötig, solange Sie seinen anderen Vorschlägen folgen:Erstellen Sie einen Index für das Zeitfeld und reduzieren Sie die Anzahl der Abfragen. Dies ist mein bester Versuch, zusammen mit einer leichten Umgestaltung. Ich habe jedoch eine Reihe von Fragen und Anmerkungen.

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

Sie stellen eine MongoDB-Anfrage, um alle Daten von jedem Tag der letzten 30 Tage zu finden. Warum verwendest du nicht einfach eine Anfrage? Und wenn Sie alle Daten haben, warum filtern Sie nicht einfach die gelöschten Daten heraus?

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

Ich bin mir wirklich nicht sicher, warum Sie 60 Anfragen gestellt haben (30 * 2, eine für alle Daten, eine für nicht gelöschte). Gibt es einen bestimmten Grund, warum Sie die Daten Tag für Tag aufbauen?

Dann haben Sie:

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

Warum nicht:

N = 30
x = range(N)

len(range(x) ist gleich x , nimmt aber Rechenzeit in Anspruch. Die Art und Weise, wie Sie es ursprünglich geschrieben haben, ist nur ein wenig ... seltsam.

Hier ist mein Versuch, die Änderungen, die ich vorgeschlagen habe, so allgemein wie möglich zu machen.

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