-
Notifications
You must be signed in to change notification settings - Fork 11
/
params.json
1 lines (1 loc) · 17.5 KB
/
params.json
1
{"tagline":"","note":"Don't delete this file! It's used internally to help with page regeneration.","name":"Elasticsearch-view-plugin","google":"","body":"# Introducing the ElasticSearch View Plugin\r\n\r\nThe ElasticSearch View Plugin provides a simple way to render ElasticSearch documents in HTML, XML or text. This plugin can also be used to generate web pages that show a list of documents based on oredefined queries.\r\n\r\nElasticsearch provides a fast and simple way to retrieve a document with the [GET API](http://www.elasticsearch.org/guide/reference/api/get.html):\r\n```\r\ncurl -XGET 'http://localhost:9200/catalog/product/1'\r\n```\r\n\r\nUntil now, this API only allows to get the document in JSON format:\r\n```\r\n{\r\n \"_index\": \"catalog\",\r\n \"_type\": \"product\",\r\n \"_id\": \"1\",\r\n \"_version\": 1,\r\n \"exists\": true,\r\n \"_source\": {\r\n \"name\": \"1969 Harley Davidson Ultimate Chopper\",\r\n \"type\": \"Motorcycles\",\r\n \"brand\": \"Harley Davidson\",\r\n ...\r\n }\r\n}\r\n```\r\n\r\nAlthough this format is really useful, it is not directly presentable to a final user. The JSON format is more dedicated\r\nto be used by third party applications located at client or server side. These applications are in charge of\r\nparsing the JSON content, extracting meaningful data and rendering them in a more graphical way, for instance within a\r\nHTML page. With ElasticSearch, anyone who wants to have a graphical rendering of these documents shall install, configure\r\nand maintain such an application, which can become quite complex and require regular redelivery every time the graphic\r\ncontent of a document is modified\r\n\r\nThe ElasticSearch View Plugin can be used when you don't want to develop a dedicated application or when you wish to\r\ncontrol not only the document searches but also the way the document are displayed.\r\n\r\nThis plugin allows to create views using different templating engines (for now [MVEL](http://mvel.codehaus.org/MVEL+2.0+Basic+Templating)\r\nand [Mustache](http://mustache.github.com/) can be used) in order to generate a HTML (or XML, or anything\r\nwhich is text) display of your document and access to it threw an URL.\r\n\r\nFor example, the plugin can be used to generate a HTML page that displays our product:\r\nhttp://localhost:9200/_view/catalog/product/1\r\n\r\n![HTML view of document #1](tlrx.github.com/elasticsearch-view-plugin/samples/render_html.png)\r\n\r\nThe plugin can also be used to create several formats of views for a same type of document, if necessary with the help of\r\npredefined scripts. It can also be used to generate a specific view to show the results of predefined search queries:\r\n\r\nhttp://localhost:9200/_view/web/pages/home\r\n![HTML view of document #1](https://raw.github.com/tlrx/elasticsearch-view-plugin/gh-pages/samples/render_html_list_brand.png)\r\n\r\nIn this article, we explain how to install and configure the ElasticSearch View Plugin in order to generate HTML and XML\r\nviews of documents indexed in ElasticSearch.\r\n\r\n\r\n## Installing the plugin\r\n\r\nThe plugin can be installed as any other ElasticSearch's plugins:\r\n\r\n```\r\nbin/plugin -install tlrx/elasticsearch-view-plugin/0.0.1\r\n\r\n```\r\n\r\nThe current version of the plugin is compatible with [ElasticSearch 0.20.1](http://www.elasticsearch.org/download/2012/12/07/0.20.1.html).\r\n\r\n\r\n## Creating views for existing documents\r\n\r\nLet's imagine that we have a `catalog` index and few documents of `product` type:\r\n```\r\ncurl -XPUT 'http://localhost:9200/catalog/product/1' -d '\r\n{\r\n \"name\": \"1969 Harley Davidson Ultimate Chopper\",\r\n \"type\": \"Motorcycles\",\r\n \"brand\": \"Harley Davidson\",\r\n \"code\": \"S10_1678\",\r\n \"since\": \"1969\",\r\n \"price\": 48.34,\r\n \"description\": \"This replica features working kickstand, front suspension, gear-shift lever, footbrake lever, drive chain, wheels and steering.\",\r\n \"scale\": \"10\"\r\n}'\r\n\r\n```\r\n\r\nElasticSearch View Plugin uses the mapping's [meta data](http://www.elasticsearch.org/guide/reference/mapping/meta.html)\r\nto store all the views that are associated with a specific document type. Each view has a unique name, a scripting language,\r\na content and eventually a content type.\r\n\r\nBe careful, as the [Update API](http://www.elasticsearch.org/guide/reference/api/update.html), the `_source` field need\r\nto be enabled for this feature to work.\r\n\r\nFirst, we can create a basic view using the [MVEL templating](http://mvel.codehaus.org/MVEL+2.0+Basic+Templating) language:\r\n```\r\ncurl -XPUT 'http://localhost:9200/catalog/product/_mapping' -d '\r\n{\r\n \"product\": {\r\n \"_meta\": {\r\n \"views\": {\r\n \"default\": {\r\n \"view_lang\": \"mvel\",\r\n \"view\": \"Rendering the document #@{_id} in version @{_version} of type @{_type} from index @{_index}\"\r\n }\r\n }\r\n }\r\n }\r\n}'\r\n```\r\n\r\nThe previous command creates a view called `default`. The property `view_lang` can be used to specify the templating\r\nengine to use (default is `mvel`) whereas the `view` property holds the content of the view. When needed, a specific `content_type`\r\ncan be set. Note that the view named `default` will be used by default to render the documents of type `product`.\r\n\r\nIn MVEL, the coordinates of the document are available with `@{_id}`, `@{_type}` and `@{_index}` instructions. The original\r\n`_source` of the document can be accessed with `@{_source._x_}` where _x_ is a document property name.\r\n\r\nNow the view is created, opening the URL `http://localhost:9200/_view/catalog/product/1` in a web browser will trigger\r\nthe rendering of document with id 1. The result looks like:\r\n\r\n![Default view for product #1](https://raw.github.com/tlrx/elasticsearch-view-plugin/gh-pages/samples/render_default.png)\r\n\r\nSimple, no?\r\n\r\n\r\n### Using multiple views\r\n\r\nIn most use cases, a unique view is not sufficient. That's why the plugins allows to define many views for the same type of document,\r\n allowing differents renderings of the same document:\r\n\r\n```\r\ncurl -XPUT 'http://localhost:9200/catalog/product/_mapping' -d '\r\n{\r\n \"product\": {\r\n \"_meta\": {\r\n \"views\": {\r\n \"default\": {\r\n \"view_lang\": \"mvel\",\r\n \"view\": \"Rendering the document #@{_id} in version @{_version} of type @{_type} from index @{_index}\"\r\n },\r\n \"xml\": {\r\n \"view_lang\": \"mvel\",\r\n \"content_type\": \"text/xml\",\r\n \"view\": \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><product id=\\\"@{_id}\\\"><name>@{_source.name}</name><brand>@{_source.brand}</brand></product>\"\r\n }\r\n }\r\n }\r\n }\r\n}'\r\n```\r\n\r\n\r\nThis way the URL `http://localhost:9200/_view/catalog/product/1/xml` can be used to access to the XML view of document 1:\r\n\r\n![XML view for product #1](https://raw.github.com/tlrx/elasticsearch-view-plugin/gh-pages/samples/render_xml.png)\r\n\r\n\r\n### Rendering binary fields\r\n\r\nIf the document contains a [binary field](http://www.elasticsearch.org/guide/reference/mapping/core-types.html), the `binary`\r\nview language can be used to get an octet stream corresponding to the field value.\r\n\r\nTo illustrate that, we can add a new picture field to document 1 (the full JSON content is available on [gist](https://gist.github.com/4337853)):\r\n```\r\ncurl -XPUT 'http://localhost:9200/catalog/product/1' -d '\r\n{\r\n \"name\": \"1969 Harley Davidson Ultimate Chopper\",\r\n \"type\": \"Motorcycles\",\r\n \"brand\": \"Harley Davidson\",\r\n \"code\": \"S10_1678\",\r\n \"since\": \"1969\",\r\n \"price\": 48.34,\r\n \"description\": \"This replica features working kickstand, front suspension, gear-shift lever, footbrake lever, drive chain, wheels and steering.\",\r\n \"scale\": \"10\",\r\n \"picture\": \"/9j/4AAQSkZJRgABAQAAAQABAAD//gA7...\"\r\n}'\r\n\r\n```\r\n\r\nThe picture field contains a base64 encoded image of the Harley Davidson's logo.\r\n\r\nWe can now define two more views:\r\n* **logo**: which renders the picture as binary content\r\n* **full**: which renders the document as HTML block\r\n\r\n```\r\ncurl -XPUT 'http://localhost:9200/catalog/product/_mapping' -d '\r\n{\r\n \"product\": {\r\n \"_meta\": {\r\n \"views\": {\r\n \"default\": {\r\n \"view_lang\": \"mvel\",\r\n \"view\": \"Rendering the document #@{_id} in version @{_version} of type @{_type} from index @{_index}\"\r\n },\r\n \"xml\": {\r\n \"view_lang\": \"mvel\",\r\n \"content_type\": \"text/xml\",\r\n \"view\": \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><product id=\\\"@{_id}\\\"><name>@{_source.name}</name><brand>@{_source.brand}</brand></product>\"\r\n },\r\n \"logo\": {\r\n \"view_lang\": \"binary\",\r\n \"view\": \"_source.picture\"\r\n },\r\n \"full\": {\r\n \"view_lang\": \"mvel\",\r\n \"view\": \"<div id=\\\"product-@{_id}\\\"><img src=\\\"/_view/catalog/product/@{_id}/logo\\\"/><h2>Detail of @{_source.name.toUpperCase()}</h2><p>Year: @{_source.since}, price: @{_source.price}€</p><p>@{_source.description}</p><p>© Copyright @{_source.brand}</p></div>\"\r\n }\r\n }\r\n }\r\n }\r\n}'\r\n```\r\n\r\nThe URL `http://localhost:9200/_view/catalog/product/1/logo` can be used to get the picture of the product, whereas\r\n `http://localhost:9200/_view/catalog/product/1/full` renders the full HTML view:\r\n\r\n![HTML view of document #1](https://raw.github.com/tlrx/elasticsearch-view-plugin/gh-pages/samples/render_html.png)\r\n\r\n\r\n## Using preloaded templates\r\n\r\nSimilar to the [scripting module](http://www.elasticsearch.org/guide/reference/modules/scripting.html), the ElasticSearch\r\nView Plugin supports predefined templates scripts.\r\n\r\nThe scripts must be placed under the `config/views` directory and then referencing them by the script name. The way to\r\nreference a script differs according to the view language.\r\n\r\nFor example, we can create the file `config/views/copyright.mv` with the following content:\r\n```\r\n<p>© Copyright @{_source.brand}</p>\r\n```\r\n\r\nThe `.mv` extension indicates that the file contains a template written in MVEL.\r\n\r\nAfter a cluster restart, we will be able to update the `full` view in order to use the preloaded template script (note the\r\n@includeNamed{} instruction):\r\n```\r\n...\r\n \"full\": {\r\n \"view_lang\": \"mvel\",\r\n \"view\": \"<div id=\\\"product-@{_id}\\\"><img src=\\\"/_view/catalog/product/@{_id}/logo\\\"/><h2>Detail of @{_source.name.toUpperCase()}</h2><p>Year: @{_source.since}, price: @{_source.price}€</p><p>@{_source.description}</p>@includeNamed{\\\"copyright\\\"}</div>\"\r\n }\r\n...\r\n ```\r\n\r\nPreloaded templates are great candidates for code o text that are used in mulitple views.\r\n\r\n## Creating complete views from queries\r\n\r\nThe plugin allows to create custom views from query hits. Everytime such a view is requested, a set of predefined queries\r\nare executed and the results are used to create the view. Such views are stored in ElasticSearch as standard documents.\r\n\r\nThis kind of view is really powerful and are a simple way to create complete web pages.\r\n\r\nFirst, let's create a more complex template called `list-of-products` and stored in the file `config/views/list-of-products.mv`:\r\n```html\r\n<!DOCTYPE html>\r\n<html lang=\"en\">\r\n <head>\r\n <meta charset=\"utf-8\">\r\n <title>@{title}</title>\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <meta name=\"description\" content=\"\">\r\n <meta name=\"author\" content=\"\">\r\n <link href=\"http://twitter.github.com/bootstrap/assets/css/bootstrap.css\" rel=\"stylesheet\">\r\n <style>\r\n body {\r\n padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */\r\n }\r\n </style>\r\n\r\n <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->\r\n <!--[if lt IE 9]>\r\n <script src=\"http://html5shim.googlecode.com/svn/trunk/html5.js\"></script>\r\n <![endif]-->\r\n </head>\r\n\r\n <body>\r\n <div class=\"navbar navbar-inverse navbar-fixed-top\">\r\n <div class=\"navbar-inner\">\r\n <div class=\"container\">\r\n <a class=\"btn btn-navbar\" data-toggle=\"collapse\" data-target=\".nav-collapse\">\r\n <span class=\"icon-bar\"></span>\r\n <span class=\"icon-bar\"></span>\r\n <span class=\"icon-bar\"></span>\r\n </a>\r\n <a class=\"brand\" href=\"#\">Catalog</a>\r\n <div class=\"nav-collapse collapse\">\r\n <ul class=\"nav\">\r\n <li class=\"active\"><a href=\"#\">List of products</a></li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"container\">\r\n <h1>List of products with scale 1:10</h1>\r\n <table class=\"table table-striped\">\r\n <thead>\r\n <tr>\r\n <th>Code</th>\r\n <th>Name</th>\r\n <th>Brand</th>\r\n <th>Year</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @foreach{item : _queries.products_with_size_1_10}\r\n <tr>\r\n <td>@{item._source.code}</td>\r\n <td>@{item._source.name}</td>\r\n <td>@{item._source.brand}</td>\r\n <td>@{item._source.since}</td>\r\n </tr>\r\n @end{}\r\n </tbody>\r\n </table>\r\n </div>\r\n </body>\r\n</html>\r\n```\r\n\r\nNext, we can create a view:\r\n```\r\ncurl -XPUT \"http://localhost:9200/catalog/list-of-products-by-size/1:10\" -d \"{\r\n \\\"views\\\":{\r\n \\\"default\\\":{\r\n \\\"view_lang\\\": \\\"mvel\\\",\r\n \\\"queries\\\": {\r\n \\\"products_with_size_1_10\\\": {\r\n \\\"indices\\\": \\\"catalog\\\",\r\n \\\"types\\\": [\\\"product\\\"],\r\n \\\"query\\\" : {\r\n \\\"constant_score\\\" : {\r\n \\\"filter\\\" : {\r\n \\\"term\\\" : { \\\"scale\\\" : \\\"10\\\"}\r\n }\r\n }\r\n }\r\n }\r\n },\r\n \\\"view\\\" : \\\"@includeNamed{'list-of-products'; title='List of products'}\\\"\r\n }\r\n }\r\n}\"\r\n```\r\n\r\nNote that the view is indexed in `catalog` index with the `list-of-products-by-size` document type and id `1:10`. It defines\r\na view called `default` (but could have another name) and uses the `list-of-products.mv` template to render a list\r\nof products.\r\n\r\nThe list of products is defined by the `products_with_size_1_10` query in the `queries` field of the view. This query\r\nselects 10 products that have a scale of 1:10.\r\n\r\nIf you look closely at the previous template, you can see the following code:\r\n```\r\n@foreach{item : _queries.products_with_size_1_10}\r\n <tr>\r\n <td>@{item._source.code}</td>\r\n <td>@{item._source.name}</td>\r\n <td>@{item._source.brand}</td>\r\n <td>@{item._source.since}</td>\r\n </tr>\r\n@end{}\r\n```\r\n\r\nThis code uses a MVEL templating syntax `@foreach{}...@end{}` that iterates over the hits provided by the\r\n`products_with_size_1_10` query in order to construct a dynamic table of products that will be rendered in the\r\nfinal HTML page. Of course, multiple queries can be used in the same view.\r\n\r\nThe result is available at `http://localhost:9200/_view/catalog/list-of-products-by-size/1:10` and looks like:\r\n\r\n![List of products with scale 1:10](https://raw.github.com/tlrx/elasticsearch-view-plugin/gh-pages/samples/render_html_list.png)\r\n\r\n\r\n## Going further...\r\n\r\n### Using Mustache\r\n\r\nThe plugin [elasticsearch-view-mustache-plugin](https://github.com/tlrx/elasticsearch-view-mustache-plugin) adds\r\n[Mustache](http://mustache.github.com/) as templating language for views.\r\n\r\nMustache is a great templating engine that supports template encapsulation. To defined views with Mustache template engine,\r\nuse `\"view_lang\": \"mustache\"`.\r\n\r\nSome sample usage of this plugin can be found in the Github project.\r\n\r\n### Rewriting URLs with Apache2\r\n\r\nApache2 server with mod_proxy and mod_rewrite can be used to redirect ElasticSearch Views Plugin URLs to better looking URLs.\r\n\r\nThe goal is to have nicer URLs like `http://www.domain.com/catalog/list-of-products-by-size/1:10` that points\r\nto internal `http://localhost:9200/_view/catalog/list-of-products-by-size/1:10`.\r\n\r\nHere is a basic sample of such URL rewriting:\r\n```\r\nRewriteEngine on\r\nRewriteRule ^catalog/(.*)$ http://localhost:9200/_view/catalog/$1 [P,L]\r\n```\r\n\r\n\r\n\r\nWe hope that this plugin will be as useful for you as it is for us, and we welcome your feedback and comments about this new plugin.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n"}