{"action":"reopened","issue":{"url":"https://api.github.com/repos/algolia/algoliasearch-helper-js/issues/137","labels_url":"https://api.github.com/repos/algolia/algoliasearch-helper-js/issues/137/labels{/name}","comments_url":"https://api.github.com/repos/algolia/algoliasearch-helper-js/issues/137/comments","events_url":"https://api.github.com/repos/algolia/algoliasearch-helper-js/issues/137/events","html_url":"https://github.com/algolia/algoliasearch-helper-js/issues/137","id":93236957,"number":137,"title":"API proposal: hierarchicalFacets","user":{"login":"vvo","id":123822,"avatar_url":"https://avatars.githubusercontent.com/u/123822?v=3","gravatar_id":"","url":"https://api.github.com/users/vvo","html_url":"https://github.com/vvo","followers_url":"https://api.github.com/users/vvo/followers","following_url":"https://api.github.com/users/vvo/following{/other_user}","gists_url":"https://api.github.com/users/vvo/gists{/gist_id}","starred_url":"https://api.github.com/users/vvo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vvo/subscriptions","organizations_url":"https://api.github.com/users/vvo/orgs","repos_url":"https://api.github.com/users/vvo/repos","events_url":"https://api.github.com/users/vvo/events{/privacy}","received_events_url":"https://api.github.com/users/vvo/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/algolia/algoliasearch-helper-js/labels/enhancement","name":"enhancement","color":"84b6eb"}],"state":"open","locked":false,"assignee":{"login":"vvo","id":123822,"avatar_url":"https://avatars.githubusercontent.com/u/123822?v=3","gravatar_id":"","url":"https://api.github.com/users/vvo","html_url":"https://github.com/vvo","followers_url":"https://api.github.com/users/vvo/followers","following_url":"https://api.github.com/users/vvo/following{/other_user}","gists_url":"https://api.github.com/users/vvo/gists{/gist_id}","starred_url":"https://api.github.com/users/vvo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vvo/subscriptions","organizations_url":"https://api.github.com/users/vvo/orgs","repos_url":"https://api.github.com/users/vvo/repos","events_url":"https://api.github.com/users/vvo/events{/privacy}","received_events_url":"https://api.github.com/users/vvo/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/algolia/algoliasearch-helper-js/milestones/9","html_url":"https://github.com/algolia/algoliasearch-helper-js/milestones/2.2.0","labels_url":"https://api.github.com/repos/algolia/algoliasearch-helper-js/milestones/9/labels","id":1196324,"number":9,"title":"2.2.0","description":"","creator":{"login":"bobylito","id":393765,"avatar_url":"https://avatars.githubusercontent.com/u/393765?v=3","gravatar_id":"","url":"https://api.github.com/users/bobylito","html_url":"https://github.com/bobylito","followers_url":"https://api.github.com/users/bobylito/followers","following_url":"https://api.github.com/users/bobylito/following{/other_user}","gists_url":"https://api.github.com/users/bobylito/gists{/gist_id}","starred_url":"https://api.github.com/users/bobylito/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bobylito/subscriptions","organizations_url":"https://api.github.com/users/bobylito/orgs","repos_url":"https://api.github.com/users/bobylito/repos","events_url":"https://api.github.com/users/bobylito/events{/privacy}","received_events_url":"https://api.github.com/users/bobylito/received_events","type":"User","site_admin":false},"open_issues":6,"closed_issues":2,"state":"open","created_at":"2015-07-07T07:47:21Z","updated_at":"2015-07-24T17:00:20Z","due_on":null,"closed_at":null},"comments":13,"created_at":"2015-07-06T09:53:43Z","updated_at":"2015-07-24T17:00:20Z","closed_at":null,"body":"I recently had to do a POC using hierarchical facets navigation. Something like:\r\n\r\n```\r\n- All products (10)\r\n  - food (10)\r\n    - fruits (10)\r\n      - bananas (2)\r\n      - kiwis (3)\r\n      - oranges (5)\r\n        - portugal (5)\r\n```\r\n\r\nIn this example, we clicked on \"food\" > \"fruits\" > \"oranges\" > \"portugal\"\r\n\r\nThis is a not so easy task to do and one that was asked by a good number of clients lately.\r\nWe already talked about it in #24 and it has been done differently by multiple people.\r\n\r\nTo simplify this use case for our clients, I propose to add a new API.\r\n\r\n## Acknowledgments\r\n\r\nFor hierarchical faceting to work well, we'll need the index to have certain attributes storing the hierarchical path.\r\n\r\nThose attributes can have different names but their values must reflect the hierarchical path.\r\n\r\nExample:\r\n\r\n```json\r\n{\r\n  \"name\": \"Portuguese oranges\",\r\n  \"categories\": {\r\n    \"level0\": \"food\",\r\n    \"level1\": \"food > fruits\",\r\n    \"level2\": \"food > fruits > oranges\",\r\n    \"level3\": \"food > fruits > oranges > portugal\"\r\n  }\r\n}\r\n```\r\n\r\nWhy do we need to have the full path at every level? Because you may have `oranges` category in another `level1` category like `food > smoothies`.\r\n\r\nThus when we will ask for `level2 === oranges` we will not be able to know what are the oranges we want, oranges fruits or oranges smoothies?\r\n\r\n## Examples\r\n\r\n### Simple usage\r\n\r\nWe should aim for this simple usage most of the time.\r\n\r\nIndex objects:\r\n```json\r\n{\r\n  \"name\": \"Portuguese oranges\",\r\n  \"categories\": {\r\n    \"level0\": \"food\",\r\n    \"level1\": \"food > fruits\",\r\n    \"level2\": \"food > fruits > oranges\",\r\n    \"level3\": \"food > fruits > oranges > portugal\"\r\n  }\r\n}\r\n```\r\n\r\nJS code:\r\n```js\r\nvar helper = algoliasearchHelper(client, indexName, {\r\n  hierarchicalFacets: ['categories']\r\n});\r\n\r\nhelper.toggleRefine('categories', 'food > fruits > oranges > portugal');\r\n\r\nhelper.search();\r\n\r\nhelper.on('result', function(content) {\r\n  console.log(content.hierarchicalFacets);\r\n  // [{\r\n  //   name: 'categories',\r\n  //   isRefined: true,\r\n  //   path: '',\r\n  //   count: 10,\r\n  //   data: [{\r\n  //     name: 'food',\r\n  //     path: 'food',\r\n  //     isRefined: true,\r\n  //     count: 10,\r\n  //     data: [{\r\n  //       name: 'fruits',\r\n  //       path: 'food > fruits',\r\n  //       isRefined: true,\r\n  //       count: 10,\r\n  //       data: [{\r\n  //         name: 'bananas',\r\n  //         path: 'food > fruits > bananas',\r\n  //         isRefined: false,\r\n  //         data: null\r\n  //         count: 2,\r\n  //       }, {\r\n  //           name: 'kiwis',\r\n  //           path: 'food > fruits > kiwis',\r\n  //           isRefined: false,\r\n  //           data: null\r\n  //           count: 3,\r\n  //         },\r\n  //         path: 'food > fruits > oranges',\r\n  //         name: 'oranges',\r\n  //         data: [{\r\n  //           name: 'portugal',\r\n  //           isRefined: true,\r\n  //           data: null\r\n  //           count: 5\r\n  //         }]\r\n  //       }]\r\n  //     }]\r\n  //   }]\r\n  // }]\r\n});\r\n```\r\n\r\n### Advanced usage: multiple hierarchical facets usage\r\n\r\nWhat if we have:\r\n```json\r\n{\r\n  \"name\": \"Portuguese oranges\",\r\n  \"categories\": {\r\n    \"level0\": \"food\",\r\n    \"level1\": \"food > fruits\",\r\n    \"level2\": \"food > fruits > oranges\",\r\n    \"level3\": \"food > fruits > oranges > portugal\"\r\n  },\r\n  \"colors\": {\r\n    \"level0\": \"dark\",\r\n    \"level1\": \"dark > orange\",\r\n    \"level1\": \"dark > dark light > orange\",\r\n  }\r\n}\r\n```\r\n \r\nThen we want to have two different hierarchical facets:\r\n```js\r\nvar helper = algoliasearchHelper(client, indexName, {\r\n  hierarchicalFacets: ['categories', 'colors']\r\n});\r\n```\r\n\r\n### Advanced usage: specifying different attributes for levels\r\n\r\nWhat if we have:\r\n```json\r\n{\r\n  \"name\": \"Portuguese oranges\",\r\n  \"categories_lvl0\": \"food\",\r\n  \"categories_lvl1\": \"food > fruits\",\r\n  \"categories_lvl2\": \"food > fruits > oranges\",\r\n  \"categories_lvl3\": \"food > fruits > oranges > portugal\"\r\n  }\r\n}\r\n```\r\n?\r\n\r\nThen we want to be specific:\r\n```js\r\nvar helper = algoliasearchHelper(client, indexName, {\r\n  hierarchicalFacets: [{\r\n    name: 'categories',\r\n    // must be given in an order that reflects the levels\r\n    attributes: ['categories_lvl0', 'categories_lvl1', 'categories_lvl2', 'categories_lvl3']\r\n  }]\r\n});\r\n```\r\n\r\n### Advanced usage: specifying the separator \r\n\r\nWhat if our categories are separated with `|` instead of `>`?\r\n\r\n```js\r\nvar helper = algoliasearchHelper(client, indexName, {\r\n  hierarchicalFacets: [{\r\n    name: 'categories',\r\n    separator: '|'\r\n  }]\r\n});\r\n```\r\n\r\n### Advanced usage: specifying the separator \r\n\r\nWhat if our categories are separated with `|` instead of `>`?\r\n\r\n```js\r\nvar helper = algoliasearchHelper(client, indexName, {\r\n  hierarchicalFacets: [{\r\n    name: 'categories',\r\n    separator: '|'\r\n  }]\r\n});\r\n```\r\n\r\nWhat do you think?\r\n\r\n### TODO\r\n\r\n- ~~[ ] `isRefined` flag should be consistent across facets~~\r\n- ~~[ ] provide some documentation on how to render this using Hogan or mustache (recursive template)~~\r\n- [x] add a method to get the current breadcrumb\r\n- ~~[ ] add a hidden _href property on data, might be useful so let's try~~"}}