2012-08-17 22 views
7

Sto cercando di utilizzare rmongodb per recuperare informazioni da un database MongoDB per un'ulteriore elaborazione in R. Tuttavia, ho alcune difficoltà per iniziare veramente. Questo funziona:Query in MongoDB

cursor <- mongo.find(mongo, "people", query=list(last.name="Smith", first.name="John"), 
       fields=list(address=1L, age=1L)) 
while (mongo.cursor.next(cursor)){ 
    print(mongo.cursor.value(cursor))} 

Ora, che cosa se voglio trovare persone il cui nome di battesimo è o "John" o "Bob" o "Catherine"? Ho provato query=list(last.name="Smith", first.name=c(John, Bob, Catherine)) ma questo non ha funzionato. Sostituire = con % non ha funzionato neanche.

altro problema è che il contenuto del database è nidificato, il che significa che hanno le sottostrutture, subsubtrees ecc, ad esempio, per l'entrata first.name="John", last.name="Smith" potrei avere voci secondarie come address, age, occupation, e per l'occupazione di nuovo mi potrebbe avere categorie come le sottostrutture (ad esempio anni dal 2005 al 2012 e per ogni anno avrò una voce come "disoccupato", "impiegato", "imprenditore"). Quindi, cosa succede se voglio trovare tutte le persone con nome "John" che hanno 40 anni e sono state disoccupate nel 2010? Come sarebbe la query?

EDIT come risposta a Stennie: Ecco un esempio della struttura del mio database e della query che sto cercando di fare. Immagina che gli alunni di un'università siano stati suddivisi in gruppi (ad esempio "studenti molto bravi", "bravi studenti" e così via). Ogni gruppo contiene quindi un elenco di persone che sono state assegnate a questo gruppo insieme ai loro dettagli.

(0){..} 
    _id : (Object ID) class id 
    groupname: (string) unique name for this group (e.g. "beststudents") 
    members[11] 
     (0){..} 
      persid : (integer) 1 
      firstname: (string) 
      surname: (string) 
      age: (integer) 
      occupation: (string) 
     (1){..} 
      persid : (integer) 2 
      firstname: (string) 
      surname: (string) 
      age: (integer) 
      occupation: (string) 
#  and so on until (10){..} 
(1){..} 
    _id : (Object ID) class id 
    groupname: (string) unique name for this group 
    members[3] 
     (0){..} 
      persid : (integer) 1 
      firstname: (string) 
      surname: (string) 
      age: (integer) 
      occupation: (string) 
#  and so on until (2){..} 
# and many more 

Ora supponiamo che mi interessa nei gruppi con i nomi "migliori studenti" e "buoni studenti", e vorrei ottenere "cognome" e "occupazione" per ogni membro di ciascuno di questi gruppi come oggetto R per fare alcuni grafici, statistiche o altro. E forse vorrei anche perfezionare questa richiesta per ottenere solo quei membri che hanno meno di 40 anni. Ora, dopo aver letto la risposta di Stennie, ho provato in questo modo:

cursor <- mongo.find(mongo, "test.people", 
      list(groupname=list('$in'=c("beststudents", "goodstudents")), 
       members.age=list('$lt'=40) # I haven't tried this with my DB, so I hope this line is right 
       ), 
      fields=list(members.surname=1L, members.occupation=1L) 
     ) 
count <- mongo.count(mongo, "test.people", 
      list(groupname=list('$in'=c("beststudents", "goodstudents")), 
       members.age=list('$lt'=40) 
       ) 
     ) 
surnames <- vector("character", count) 
occupations <- vector("character", count) 
i <- 1 
while (mongo.cursor.next(cursor)) { 
    b <- mongo.cursor.value(cursor) 
    surnames[i] <- mongo.bson.value(b, "members.surname") 
    occupations[i] <- mongo.bson.value(b, "members.occupation") 
    i <- i + 1 
} 
df <- as.data.frame(list(surnames=surnames, occupations=occupations)) 

Non c'è alcun messaggio di errore dopo l'esecuzione di questo, ma ottengo un frame di dati vuoto. Cosa c'è di sbagliato con questo codice?

+0

potete inserire un documento di esempio? Idealmente un esempio ridotto che mostra l'annidamento tipico per la tua query. – Stennie

risposta

3

Ora, che cosa se voglio trovare persone il cui nome di battesimo è o "John" o "Bob" o "Catherine"?

È possibile utilizzare il $in operator per questo:

cursor <- mongo.find(mongo, "test.people", 
    list(last.name="Smith", 
     first.name=list('$in'=c('John','Bob','Catherine')) 
    ) 
) 

Sarebbe la pena di avere una lettura della pagina MongoDB Advanced Queries così come Dot Notation (Reaching Into Objects).

Un altro problema è che il contenuto del database è nidificato, il che significa ho sottostrutture, subsubtrees ecc

La struttura dei dati suoni potenzialmente impegnativo per manipolare; sarebbe necessario un esempio pratico di un documento per cercare di illustrare la query.

E se voglio trovare tutte le persone con nome "John", che sono 40 anni e erano disoccupati nel 2010? Come sarebbe la query?

fare qualche ipotesi sulla struttura dei dati, ecco un esempio di un semplice "e" query:

cursor <- mongo.find(mongo, "test.people", 
    list(
     first.name='John', 
     fy2012.job='unemployed', 
     age = 40 
    ) 
) 
+0

Grazie per la tua risposta, è utile. Ho inserito un esempio più dettagliato con un codice che ho provato dopo aver letto la tua risposta, ma non ha funzionato come dovrebbe. Hai un'idea di qual è il problema? – AnjaM

+0

@AnjaM: Ci scusiamo, il tuo ultimo commento qui è stato aggiunto, aggiungendo anche un nuovo esempio nella descrizione. Sei riuscito a risolvere il problema con quella query? In caso contrario, è probabilmente meglio aggiungere una domanda separata. – Stennie