{"action":"opened","issue":{"url":"https://api.github.com/repos/cozy/cozy-stack/issues/45","repository_url":"https://api.github.com/repos/cozy/cozy-stack","labels_url":"https://api.github.com/repos/cozy/cozy-stack/issues/45/labels{/name}","comments_url":"https://api.github.com/repos/cozy/cozy-stack/issues/45/comments","events_url":"https://api.github.com/repos/cozy/cozy-stack/issues/45/events","html_url":"https://github.com/cozy/cozy-stack/issues/45","id":182748397,"number":45,"title":"[Exploration] Couchdb MapReduce vs Indexes","user":{"login":"aenario","id":1580287,"avatar_url":"https://avatars.githubusercontent.com/u/1580287?v=3","gravatar_id":"","url":"https://api.github.com/users/aenario","html_url":"https://github.com/aenario","followers_url":"https://api.github.com/users/aenario/followers","following_url":"https://api.github.com/users/aenario/following{/other_user}","gists_url":"https://api.github.com/users/aenario/gists{/gist_id}","starred_url":"https://api.github.com/users/aenario/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aenario/subscriptions","organizations_url":"https://api.github.com/users/aenario/orgs","repos_url":"https://api.github.com/users/aenario/repos","events_url":"https://api.github.com/users/aenario/events{/privacy}","received_events_url":"https://api.github.com/users/aenario/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-10-13T10:08:27Z","updated_at":"2016-10-13T10:08:27Z","closed_at":null,"body":"There is two way to requests documents in Couchdb2. \r\n\r\n### MapReduce\r\nby PUTing a `_design/xxxx` document, with a map view, which can be arbiraty complex\r\n```javascript\r\n// simple : sort all doc by name \r\nfunction(contact){\r\n     emit(contact.name)\r\n}\r\n```\r\n```javascript\r\n// more complex : tags\r\nfunction(note){\r\n    for(var i=0, l=note.tags.length; i<l; i++{\r\n         emit(note.tags[i], note.title)\r\n    }\r\n}\r\n```\r\n\r\n```javascript\r\n// complex & arbitrary : get all done todo, sorted by hour of completion, \r\n// to see at what point of the day we are more efficient.\r\nfunction(todo){\r\n    if(todo.done){\r\n         emit(new Date(todo.doneDate).getHours(), todo.complexity)\r\n    }\r\n}\r\n```\r\n\r\nThis construct an index though the key (first argument of emit), which can they be requested with key=xx or sliced with startKey=xxxx... This returns the value (second argument of emit) or the full doc with include_docs=true.\r\n\r\nThis is very powerful, and allow for very complex query and statistics\r\n\r\n### Indexes & Mango\r\nby POSTing an index \r\n```json\r\n{\r\n    \"index\": { \"fields\": [\"firstname\", \"lastname\"]  },\r\n}\r\n```\r\nwe can then request it using the mango query language\r\n```json\r\n{\r\n \"selector\": {\"firstname\": \"John\"},\r\n \"sort\": [\"lastname\"],\r\n \"limit\": 2,\r\n}\r\n```\r\n\r\nThis is erlang powered and thus faster as there is no need to format the doc to JSON and pass it through IPC to the internal couchdb JS server. \r\nHowever it is more limited : it is impossible to do manipulation of the data (like extracting hour from the datetime in the map exemple). And, more limiting, it is impossible to emit for each value of an array or map (tag exemple - [couchdb isssue](https://issues.apache.org/jira/browse/COUCHDB-2867)).\r\n\r\nThe vast majority of query from the previous stack and application can be made using the index&mango system : sort by field, get docs where fields is x, where field start with x. \r\nA few query could not ( [exemple](https://github.com/cozy/cozy-emails/blob/304a6364d2a64c0f6df428b93b230abbce854cfa/server/models/requests.coffee#L13) , [exemple2](https://github.com/cozy/cozy-calendar/blob/da36ca6db78b95c8c5551e4c3ec6555737a2a1b7/server/models/requests.coffee#L39) ) \r\n\r\n\r\nMy opinion is that we should focus on Indexes&Mango at first as it is faster, simpler and clearer for our firsts uses cases : get all files & folders by parentid. However we will need to support JS map reduce at some point in the future, but we should make it a less desirable option when proper client-side denormalisation of the document would allow to use indexes&mango (adding a completed_hour field in our task example)"}}
{"actor":{"display_login":"aenario"}}