2012-08-17 11 views
7

Ich versuche rmongodb zu verwenden, um Informationen aus einer MongoDB-Datenbank für die weitere Verarbeitung in R abzurufen. Allerdings habe ich einige Schwierigkeiten, wirklich anzufangen. Dies funktioniert:Abfragen 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))} 

Nun, was ist, wenn ich die Leute, deren Namen finden will, ist entweder „John“ oder „Bob“ oder „Catherine“? Ich habe versucht query=list(last.name="Smith", first.name=c(John, Bob, Catherine)), aber das hat nicht geklappt. Das Ersetzen = durch % funktionierte auch nicht.

Ein weiteres Problem ist, dass der Datenbankinhalt verschachtelt ist, was bedeutet, dass ich Teilbäume, subsubtrees etc. Zum Beispiel für den Eintrag first.name="John", last.name="Smith" ich Untereinträge wie address, age, occupation haben könnte, und für die Besetzung wieder könnte ich Kategorien Unterstrukturen (zB Jahre hat von 2005 bis 2012 und für jedes Jahr hätte ich einen Eintrag wie "arbeitslos", "Angestellter", "Unternehmer". Was ist, wenn ich alle Menschen mit dem Vornamen "John" finden möchte, die 40 Jahre alt sind und 2010 arbeitslos waren? Wie würde die Abfrage aussehen?

EDIT als Antwort auf Stennie: Hier ist ein Beispiel für die Struktur meiner Datenbank und die Abfrage, die ich versuche zu tun. Stellen Sie sich vor, dass Alumni einer Universität in Gruppen unterteilt wurden (z. B. "sehr gute Schüler", "gute Schüler" usw.). Jede Gruppe enthält dann eine Liste der Personen, die dieser Gruppe mit ihren Details zugewiesen wurden.

(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 

Nun nehmen wir an, dass ich mit den Namen in den Gruppen interessiert am „besten Studenten“ und „gute Schüler“, und möchte „Nachname“ erhalten und „Besetzung“ für jedes Mitglied jeder dieser Gruppen als ein R-Objekt, um einige Plots, Statistiken oder was auch immer zu machen. Und vielleicht möchte ich auch diese Anfrage verfeinern, um nur die Mitglieder zu bekommen, die jünger als 40 Jahre alt sind. Jetzt, nach Stennie Antwort gelesen zu haben, versuchte ich es auf diese Weise:

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

Es gibt keine Fehlermeldung dies nach dem Laufen, aber ich erhalte einen leeren Datenrahmen. Was ist mit diesem Code falsch?

+0

Können Sie ein Beispiel Belegs? Idealerweise ein reduziertes Beispiel, das die typische Verschachtelung für Ihre Anfrage zeigt. – Stennie

Antwort

3

Nun, was ist, wenn ich will Menschen, die finden Vornamen entweder „John“ oder „Bob“ oder „Catherine“?

können Sie die $in operator für diesen Einsatz:

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

es sich lohnen würde, sowie Dot Notation (Reaching Into Objects) eine Lese der MongoDB Advanced Queries Seite mit.

Ein weiteres Problem ist, dass der Datenbankinhalt verschachtelt ist, was bedeutet, Ich habe Teilbäume, subsubtrees usw.

Die Datenstruktur klingt möglicherweise schwierig zu manipulieren; würde ein praktisches Beispiel eines Dokuments benötigen, um zu versuchen, die Abfrage zu veranschaulichen.

Also was, wenn ich alle Leute mit dem Vornamen "John" finden möchte, die 40 Jahre alt sind und 2010 arbeitslos waren? Wie würde die Abfrage aussehen?

machen einige Annahmen über die Datenstruktur, hier ist ein Beispiel für eine einfache „und“ query:

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

Vielen Dank für Ihre Antwort, es ist hilfreich. Ich habe ein ausführlicheres Beispiel mit einem Code eingefügt, den ich nach dem Lesen Ihrer Antwort ausprobiert habe, aber das hat nicht so funktioniert, wie es sollte. Hast du eine Vorstellung davon, was das Problem ist? – AnjaM

+0

@AnjaM: Entschuldigung, verpasste Ihren letzten Kommentar hier, der auch ein neues Beispiel in der Beschreibung hinzufügt. Konnten Sie das Problem mit dieser Abfrage lösen? Wenn nicht, ist es wahrscheinlich besser, als separate Frage hinzuzufügen. – Stennie