Significato della funzione mappa in couchdb-pythons ViewField
-
28-10-2019 - |
Domanda
Sto utilizzando couchdb.mapping in uno dei miei progetti. Ho una classe chiamata SupportCase
derivata da Document
che contiene tutti i campi che desidero.
Il mio database (chiamato admin
) contiene più tipi di documenti. Ho un campo type
in tutti i documenti che utilizzo per distinguerli. Ho molti documenti di tipo "case"
che desidero visualizzare utilizzando una vista. Ho un documento di progettazione chiamato support
con una vista al suo interno chiamata cases
. Se richiedo i risultati di questa visualizzazione utilizzando db.view("support/cases)
, ricevo un elenco di Row
che hanno quello che voglio.
Tuttavia, voglio che in qualche modo questo sia avvolto dalla classe SupportCase
in modo da poter chiamare una singola funzione e ottenere un elenco di tutti i SupportCase
s nel sistema. Ho creato una proprietà ViewField
@ViewField.define('cases')
def all(self, doc):
if doc.get("type","") == "case":
yield doc["_id"], doc
Ora, se chiamo SupportCase.all(db)
, ricevo tutti i casi.
Quello che non capisco è se questa vista è precalcolata e archiviata nel database o eseguita su richiesta in modo simile a db.query
. Se è il secondo, sarà lento e voglio usare una vista precalcolata. Come posso farlo?
Soluzione
Penso che ciò di cui hai bisogno sia:
@classmethod
def all(cls):
result = cls.view(db, "support/all", include_docs=True)
return result.rows
La classe Document
ha un metodo di classe view
che avvolge le righe in base alla classe su cui è chiamata.Quindi quanto segue ti restituisce un ViewResult
con righe di tipo SupportCase
e prendendo .rows
che fornisce un elenco di casi di supporto.
SupportCase.view(db, viewname, include_docs=True)
E non credo sia necessario entrare nella magia di ViewField.Ma lasciami spiegare come funziona.Considera il seguente esempio dalla documentazione CouchDB-python
.
class Person(Document):
@ViewField.define('people')
def by_name(doc):
yield doc['name'], doc
Penso che questo sia equivalente a:
class Person(Document):
@classmethod
def by_name(cls, db, **kw):
return cls.view(db, **kw)
Con la funzione originale allegata a People.by_name.map_fun
.
Altri suggerimenti
La funzione map è per certi versi analoga a un indice in un database relazionale.Non viene ripetuto ogni volta e quando vengono aggiunti nuovi documenti il modo in cui viene aggiornato non richiede di rifare tutto (è una specie di struttura ad albero).
Questo ha un bel riepilogo
ViewField utilizza una vista predefinita quindi, una volta creato, sarà veloce.Sicuramente non utilizza una visualizzazione temporanea.