{"action":"created","issue":{"url":"https://api.github.com/repos/jeroenooms/mongolite/issues/3","labels_url":"https://api.github.com/repos/jeroenooms/mongolite/issues/3/labels{/name}","comments_url":"https://api.github.com/repos/jeroenooms/mongolite/issues/3/comments","events_url":"https://api.github.com/repos/jeroenooms/mongolite/issues/3/events","html_url":"https://github.com/jeroenooms/mongolite/issues/3","id":67421051,"number":3,"title":"Could mongo$find() have an argument to return list?","user":{"login":"durtal","id":6617622,"avatar_url":"https://avatars.githubusercontent.com/u/6617622?v=3","gravatar_id":"","url":"https://api.github.com/users/durtal","html_url":"https://github.com/durtal","followers_url":"https://api.github.com/users/durtal/followers","following_url":"https://api.github.com/users/durtal/following{/other_user}","gists_url":"https://api.github.com/users/durtal/gists{/gist_id}","starred_url":"https://api.github.com/users/durtal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/durtal/subscriptions","organizations_url":"https://api.github.com/users/durtal/orgs","repos_url":"https://api.github.com/users/durtal/repos","events_url":"https://api.github.com/users/durtal/events{/privacy}","received_events_url":"https://api.github.com/users/durtal/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":7,"created_at":"2015-04-09T18:18:12Z","updated_at":"2015-07-15T10:13:25Z","closed_at":null,"body":"First off, really promising package, the various methods being attached to a connection keeps things very tidy.  I have been using `rmongodb` thus far, but this is a very welcome package.\r\n\r\nI asked on [twitter](https://twitter.com/UTVilla/status/586205742245486592) about whether it is (or would be) possible for `mongo$find()` to return a list.  This might be something idiosyncratic (bad?) that I am doing, or an unnecessary complication on my part, but a number of my databases contain nested objects.  One such database contains a collection of horse races, each object contains data about the race conditions, as well as data about the runners, something like:\r\n\r\n```json\r\n{\r\n    \"_id\": [\"01/04/15_7\"],\r\n    \"date\": [\"01/04/15\"],\r\n    \"race\": [7],\r\n    \"details\": {\r\n        \"race_type\": [\"all op clm\"],\r\n        \"dist\": [5],\r\n        \"surf\": [\"turf\"],\r\n        \"value\": [50000]\r\n    },\r\n    \"conditions\": {\r\n        \"race_cond\": [\"nw2 x\"],\r\n        \"clm_price\": [62500],\r\n        \"f_m\": [false],\r\n        \"runup\": [165],\r\n        \"going\": [\"firm\"]\r\n    },\r\n    \"runners\": {\r\n        \"trainer\": [\"christophe clement\", \"kelly j breen\", \"enebish ganbat\", \"charles dickey\", \"joseph calascibetta\", \"benjamin perkins jr\", \"peter d pugh\", \"benjamin perkins jr\"],\r\n        \"jockey\": [\"edgard j zayas\", \"rafael manuel hernandez\", \"angel serpa\", \"edgar s prado\", \"eddie castro\", \"angel castillo\", \"mario g pino\", \"gabriel saez\"],\r\n        \"j_clm\": [0, 0, 0, 0, 0, 0, 0, 0],\r\n        \"age\": [4, 5, 4, 5, 5, 5, 4, 4],\r\n        \"wgt\": [121, 121, 121, 123, 121, 121, 121, 121],\r\n        \"gate\": [8, 1, 3, 7, 5, 2, 6, 4],\r\n        \"pos\": [1, 2, 3, 4, 5, 6, 7, 8],\r\n        \"horse\": [\"summation time\", \"bye bye bernie\", \"wild mongolia\", \"shadow rock\", \"noble prince\", \"tango on\", \"escapist\", \"hot heir skier\"],\r\n        \"fintime\": [54.79, 54.97, 55.05, 55.12, 55.17, 55.71, 55.95, 56.42]\r\n    }\r\n}\r\n```\r\n\r\nWhen `mongo$find(query = '{\"_id\": \"01/04/15_7\"}')` is called on the above entry, it returns a dataframe with just 6 variables, `_id`, `date`, `race`, `details`, `conditions` and `runners`.  The `details`, `conditions` and `runners` variables are dataframes, structure below.  \r\n\r\n```r\r\n'data.frame':\t1 obs. of  6 variables:\r\n $ _id       : chr \"01/04/15_7\"\r\n $ date      : chr \"01/04/15\"\r\n $ race      : int 7\r\n $ details   :'data.frame':\t1 obs. of  4 variables:\r\n  ..$ race_type: chr \"all op clm\"\r\n  ..$ dist     : int 5\r\n  ..$ surf     : chr \"turf\"\r\n  ..$ value    : int 50000\r\n $ conditions:'data.frame':\t1 obs. of  5 variables:\r\n  ..$ race_cond: chr \"nw2 x\"\r\n  ..$ clm_price: num 62500\r\n  ..$ f_m      : logi FALSE\r\n  ..$ runup    : int 165\r\n  ..$ going    : chr \"firm\"\r\n $ runners   :'data.frame':\t1 obs. of  9 variables:\r\n  ..$ trainer:List of 1\r\n  .. ..$ : chr  \"christophe clement\" \"kelly j breen\" \"enebish ganbat\" \"charles dickey\" ...\r\n  ..$ jockey :List of 1\r\n  .. ..$ : chr  \"edgard j zayas\" \"rafael manuel hernandez\" \"angel serpa\" \"edgar s prado\" ...\r\n  ..$ j_clm  :List of 1\r\n  .. ..$ : int  0 0 0 0 0 0 0 0\r\n  ..$ age    :List of 1\r\n  .. ..$ : int  4 5 4 5 5 5 4 4\r\n  ..$ wgt    :List of 1\r\n  .. ..$ : int  121 121 121 123 121 121 121 121\r\n  ..$ gate   :List of 1\r\n  .. ..$ : int  8 1 3 7 5 2 6 4\r\n  ..$ pos    :List of 1\r\n  .. ..$ : int  1 2 3 4 5 6 7 8\r\n  ..$ horse  :List of 1\r\n  .. ..$ : chr  \"summation time\" \"bye bye bernie\" \"wild mongolia\" \"shadow rock\" ...\r\n  ..$ fintime:List of 1\r\n  .. ..$ : num  54.8 55 55 55.1 55.2 ...\r\n```\r\n\r\nWorking with a dataframe like that would be possible, but ideally it would be a dataframe with 8 rows (one per runner), which are unique entries for a single race, and variables such as `date`, `race`, and `race_type` (found in details object), repeated for each of the entries.  I realise this is probably hard (impossible) for a package to cater for the huge number of possible structures that a BSON/JSON object could have.  If `mongo$find()` had an option to return a list (and a list of lists when returning multiple objects from a collection), so that `details`, `conditions` and `runners` seen above structure was preserved, then it would be easy for users of mongolite to write their own functions to _unpack_ their data.  The above JSON, using `jsonlite::fromJSON`, returns a nested list like:\r\n\r\n```r\r\n$`_id`\r\n[1] \"01/04/15_7\"\r\n\r\n$date\r\n[1] \"01/04/15\"\r\n\r\n$race\r\n[1] 7\r\n\r\n$details\r\n$details$race_type\r\n[1] \"all op clm\"\r\n\r\n$details$dist\r\n[1] 5\r\n\r\n$details$surf\r\n[1] \"turf\"\r\n\r\n$details$value\r\n[1] 50000\r\n\r\n\r\n$conditions\r\n$conditions$race_cond\r\n[1] \"nw2 x\"\r\n\r\n$conditions$clm_price\r\n[1] 62500\r\n\r\n$conditions$f_m\r\n[1] FALSE\r\n\r\n$conditions$runup\r\n[1] 165\r\n\r\n$conditions$going\r\n[1] \"firm\"\r\n\r\n\r\n$runners\r\n$runners$trainer\r\n[1] \"christophe clement\"  \"kelly j breen\"       \"enebish ganbat\"      \"charles dickey\"      \"joseph calascibetta\" \"benjamin perkins jr\" \"peter d pugh\"       \r\n[8] \"benjamin perkins jr\"\r\n\r\n$runners$jockey\r\n[1] \"edgard j zayas\"          \"rafael manuel hernandez\" \"angel serpa\"             \"edgar s prado\"           \"eddie castro\"            \"angel castillo\"         \r\n[7] \"mario g pino\"            \"gabriel saez\"           \r\n\r\n$runners$j_clm\r\n[1] 0 0 0 0 0 0 0 0\r\n\r\n$runners$age\r\n[1] 4 5 4 5 5 5 4 4\r\n\r\n$runners$wgt\r\n[1] 121 121 121 123 121 121 121 121\r\n\r\n$runners$gate\r\n[1] 8 1 3 7 5 2 6 4\r\n\r\n$runners$pos\r\n[1] 1 2 3 4 5 6 7 8\r\n\r\n$runners$horse\r\n[1] \"summation time\" \"bye bye bernie\" \"wild mongolia\"  \"shadow rock\"    \"noble prince\"   \"tango on\"       \"escapist\"       \"hot heir skier\"\r\n\r\n$runners$fintime\r\n[1] 54.79 54.97 55.05 55.12 55.17 55.71 55.95 56.42\r\n```\r\n\r\nFrom the list it's easy to convert into a desired dataframe.\r\n\r\n```r\r\ndata.frame(id = race$`_id`, \r\n    date = race$date, \r\n    race = race$race, \r\n    data.frame(race$details), \r\n    data.frame(race$conditions), \r\n    data.frame(race$runners))\r\n\r\n        id     date race  race_type dist surf value race_cond clm_price   f_m runup going             trainer\r\n01/04/15_7 01/04/15    7 all op clm    5 turf 50000     nw2 x     62500 FALSE   165  firm  christophe clement\r\n01/04/15_7 01/04/15    7 all op clm    5 turf 50000     nw2 x     62500 FALSE   165  firm       kelly j breen\r\n01/04/15_7 01/04/15    7 all op clm    5 turf 50000     nw2 x     62500 FALSE   165  firm      enebish ganbat\r\n01/04/15_7 01/04/15    7 all op clm    5 turf 50000     nw2 x     62500 FALSE   165  firm      charles dickey\r\n01/04/15_7 01/04/15    7 all op clm    5 turf 50000     nw2 x     62500 FALSE   165  firm joseph calascibetta\r\n01/04/15_7 01/04/15    7 all op clm    5 turf 50000     nw2 x     62500 FALSE   165  firm benjamin perkins jr\r\n01/04/15_7 01/04/15    7 all op clm    5 turf 50000     nw2 x     62500 FALSE   165  firm        peter d pugh\r\n01/04/15_7 01/04/15    7 all op clm    5 turf 50000     nw2 x     62500 FALSE   165  firm benjamin perkins jr\r\n                 jockey j_clm age wgt gate pos          horse fintime\r\n         edgard j zayas     0   4 121    8   1 summation time   54.79\r\nrafael manuel hernandez     0   5 121    1   2 bye bye bernie   54.97\r\n            angel serpa     0   4 121    3   3  wild mongolia   55.05\r\n          edgar s prado     0   5 123    7   4    shadow rock   55.12\r\n           eddie castro     0   5 121    5   5   noble prince   55.17\r\n         angel castillo     0   5 121    2   6       tango on   55.71\r\n           mario g pino     0   4 121    6   7       escapist   55.95\r\n           gabriel saez     0   4 121    4   8 hot heir skier   56.42\r\n```\r\n\r\nHope I've explained it well. Thanks"},"comment":{"url":"https://api.github.com/repos/jeroenooms/mongolite/issues/comments/121566118","html_url":"https://github.com/jeroenooms/mongolite/issues/3#issuecomment-121566118","issue_url":"https://api.github.com/repos/jeroenooms/mongolite/issues/3","id":121566118,"user":{"login":"Spider08","id":8288667,"avatar_url":"https://avatars.githubusercontent.com/u/8288667?v=3","gravatar_id":"","url":"https://api.github.com/users/Spider08","html_url":"https://github.com/Spider08","followers_url":"https://api.github.com/users/Spider08/followers","following_url":"https://api.github.com/users/Spider08/following{/other_user}","gists_url":"https://api.github.com/users/Spider08/gists{/gist_id}","starred_url":"https://api.github.com/users/Spider08/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Spider08/subscriptions","organizations_url":"https://api.github.com/users/Spider08/orgs","repos_url":"https://api.github.com/users/Spider08/repos","events_url":"https://api.github.com/users/Spider08/events{/privacy}","received_events_url":"https://api.github.com/users/Spider08/received_events","type":"User","site_admin":false},"created_at":"2015-07-15T10:13:25Z","updated_at":"2015-07-15T10:13:25Z","body":"Great. Thanks for the awesome package"}}