{"id":15044591,"url":"https://github.com/elastic/site-search-ruby","last_synced_at":"2025-10-19T21:30:29.002Z","repository":{"id":45988802,"uuid":"198864162","full_name":"elastic/site-search-ruby","owner":"elastic","description":"Elastic Site Search Official Ruby Client","archived":false,"fork":false,"pushed_at":"2024-08-30T14:07:32.000Z","size":360,"stargazers_count":2,"open_issues_count":2,"forks_count":5,"subscribers_count":23,"default_branch":"master","last_synced_at":"2024-09-27T15:42:37.053Z","etag":null,"topics":["api-client","elastic","elastic-site-search","ruby","search","swiftype"],"latest_commit_sha":null,"homepage":"https://www.elastic.co/products/site-search","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elastic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-25T16:13:51.000Z","updated_at":"2024-08-09T08:45:34.000Z","dependencies_parsed_at":"2024-09-25T01:54:04.540Z","dependency_job_id":"565017cc-436f-466e-ae0f-08212979df0e","html_url":"https://github.com/elastic/site-search-ruby","commit_stats":{"total_commits":183,"total_committers":22,"mean_commits":8.318181818181818,"dds":0.7704918032786885,"last_synced_commit":"06ddfdc32edefc27f117ebb27b95517f9cf48ec7"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elastic%2Fsite-search-ruby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elastic%2Fsite-search-ruby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elastic%2Fsite-search-ruby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elastic%2Fsite-search-ruby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elastic","download_url":"https://codeload.github.com/elastic/site-search-ruby/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219869272,"owners_count":16555575,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-client","elastic","elastic-site-search","ruby","search","swiftype"],"created_at":"2024-09-24T20:50:46.438Z","updated_at":"2025-10-19T21:30:28.662Z","avatar_url":"https://github.com/elastic.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"https://github.com/elastic/site-search-ruby/blob/master/logo-site-search.png?raw=true\" alt=\"Elastic Site Search Logo\"\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003ca href=\"https://circleci.com/gh/elastic/site-search-ruby\"\u003e\u003cimg src=\"https://circleci.com/gh/elastic/site-search-ruby.svg?style=svg\" alt=\"CircleCI build\"\u003e\u003c/a\u003e\u003c/p\u003e\n\n\u003e A first-party Ruby client for the [Elastic Site Search API](https://swiftype.com/documentation/site-search/overview).\n\n## Contents\n\n- [Getting started](#getting-started-)\n- [Usage](#usage)\n- [Migrating from pervious versions](#migrating-from-previous-versions)\n- [Development](#development)\n- [FAQ](#faq-)\n- [Contribute](#contribute-)\n- [License](#license-)\n\n---\n\n## Getting started 🐣\n\nBefore beginning with the `elastic-site-search` gem, you should be familiar with the concepts behind the Elastic Site Search API:\n\n1. **Engines**\n2. **DocumentTypes**\n3. **Documents**\n\nAn **Engine** is a search engine.\n\nIt can contain one or more **DocumentTypes** which are collections of **Documents**.\n\nA **Document** is a collection of fields that can be queried using the Site Search API.\n\nDocuments have a special **external_id** field that ties a Document in Site Search to a record in your system. The layout of fields of the Documents belonging to a DocumentType is called a **schema**. Fields may be strings, integers, geographic locations, and so forth.\n\nThe Documents in your Engine can be searched two ways: **full-text** (`search`) or **autocomplete** (`suggest`). The difference is that autocomplete queries work on prefixes (for example, \"gla\" will match \"glass\"). This is less accurate in general, but is useful for implementing type-ahead search drop downs.\n\nYou can think of an Engine as a database, DocumentTypes as tables, and Documents as rows. Using the API, you can search an Engine for all Documents containing a word. You can also search an individual DocumentType, or any subset of DocumentTypes.\n\nThe examples in this documentation use the schema defined in the [site-search-api-example](https://github.com/swiftype/swiftype-api-example) project, which is based on YouTube. It has two DocumentTypes, **videos** and **channels**. Using the script found in the site-search-api-example project, you can create your own search engine that matches the examples and try the queries for yourself.\n\nTo learn more about the Site Search API, read the [API overview](https://swiftype.com/documentation/site-search/overview) and our [schema design tutorial](https://swiftype.com/documentation/site-search/guides/schema-design).\n\nDepends on Ruby.\n\nTo install the gem, execute:\n\n```shell\ngem install elastic-site-search\n```\n\nOr place `gem 'elastic-site-search', '~\u003e 2.2.0` in your `Gemfile` and run `bundle install`.\n\n\u003e **Note:** This client has been developed for the [Elastic Site Search](https://www.elastic.co/products/site-search/service) API endpoints only.\n\n## Usage\n\n### Configuration:\n\nBefore issuing commands to the API, configure the client with your API key:\n\n```ruby\nElastic::SiteSearch.api_key = 'YOUR_API_KEY'\n```\n\nYou can find your API key in your [Account Settings](https://app.swiftype.com/settings/account).\n\n### Create a client\n\n```ruby\nclient = Elastic::SiteSearch::Client.new\n```\n\nYou can also provide the API key when creating the client instance:\n\n```ruby\nclient = Elastic::SiteSearch::Client.new(:api_key =\u003e 'different_api_key')\n```\n\nIf the API key is provided as an option to constructor, it will override the globally configured Elastic::SiteSearch API key (if any).\n\n### Specifying an HTTP Proxy\n\n```ruby\nclient = Elastic::SiteSearch::Client.new(:api_key =\u003e 'api_key', :proxy =\u003e 'http://localhost:8888')\n```\n\nThis client will also support configuring a proxy via the environment variable `http_proxy`.\n\n### Full-text search\n\nIf you want to search for `cat` on your engine, you can use:\n\n```ruby\nresults = client.search('site-search-api-example', 'cat')\nresults['videos']   # =\u003e [{'external_id' =\u003e 'QH2-TGUlwu4', 'title' =\u003e 'Nyan Cat [original]', ... }, ... ]\nresults['channels'] # =\u003e [{'external_id' =\u003e 'UC3VHfy8e1jbDnT5TG2pjP1w', 'title' =\u003e 'saraj00n', ... }, ... ]\n```\n\nTo limit the search to only the `videos` DocumentType:\n\n```ruby\nresults = client.search_document_type('site-search-api-example', 'videos', 'cat')\nresults['videos']   # =\u003e [{'external_id' =\u003e 'QH2-TGUlwu4', 'title' =\u003e 'Nyan Cat [original]', ... }, ... ]\nresults['channels'] # =\u003e nil\n```\n\nBoth search methods allow you to specify options to filter or sort on fields, boost the weight of certain fields, calculate faceted counts, and so on. For more details on these options, review the [Search Options](https://swiftype.com/documentation/site-search/searching).\n\nHere is an example for showing only videos in the \"Pets \u0026 Animals\" category (which has ID 23):\n\n```ruby\nresults = client.search_document_type('site-search-api-example', 'videos', 'cat', {:filters =\u003e {'videos' =\u003e {:category_id =\u003e '23'}}})\n```\n\n### Autocomplete search\n\nAutocomplete (also known as suggest, prefix, or type-ahead) searches can be used to implement autocompletion. They have the same functionality as full-text searches, but work on prefixes instead of all the text. Because of this, autocomplete queries only search string fields.\n\nYou can perform a suggest query across all of your Engine's Documents:\n\n```ruby\nresults = client.suggest(\"site-search-api-example\", \"gla\")\nresults['videos'] # =\u003e [{'external_id' =\u003e 'v1uyQZNg2vE', 'title' =\u003e 'How It Feels [through Glass]', ...}, ...]\n```\n\nor just for one DocumentType:\n\n```ruby\nresults = client.suggest_document_type(\"site-search-api-example\", \"videos\", \"gla\")\nresults['videos'] # =\u003e [{'external_id' =\u003e 'v1uyQZNg2vE', 'title' =\u003e 'How It Feels [through Glass]', ...}, ...]\n```\n\nor add options to have more control over the results:\n\n```ruby\nresults = client.suggest('site-search-api-example', 'glass', {:sort_field =\u003e {'videos' =\u003e 'view_count'}, :sort_direction =\u003e {'videos' =\u003e 'desc'}})\n```\n\n### Engines\n\nRetrieve every Engine:\n\n```ruby\nengines = client.engines\n```\n\nCreate a new Engine with the name `site-search-api-example`:\n\n```ruby\nengine = client.create_engine('site-search-api-example')\n```\n\nRetrieve an Engine by `slug` or `id`:\n\n```ruby\nengine = client.engine('site-search-api-example')\nengine = client.engine('5230b9102ed960ba20000021')\n```\n\nDelete an Engine by `slug` or the `id`:\n\n```ruby\nclient.destroy_engine('site-search-api-example')\n```\n\n### Document Types\n\nList all the\n\nRetrieve `DocumentTypes`s of the Engine with the `slug` field `site-search-api-example`:\n\n```ruby\ndocument_types = client.document_types('site-search-api-example')\n```\n\nShow the second batch of documents:\n\n```ruby\ndocument_types = client.document_types('site-search-api-example', 2)\n```\n\nCreate a new DocumentType for an Engine with the name `videos`:\n\n```ruby\ndocument_type = client.create_document_type('site-search-api-example', 'videos')\n```\n\nRetrieve an DocumentType by `slug` or `id`:\n\n```ruby\ndocument_type = client.document_type('site-search-api-example', 'videos')\n```\n\nDelete a DocumentType using the `slug` or `id` of it:\n\n```ruby\nclient.destroy_document_type('site-search-api-example', 'videos')\n```\n\n### Documents\n\nRetrieve the first page of Documents of Engine `site-search-api-example` and DocumentType `videos`:\n\n```ruby\ndocuments = client.documents('site-search-api-example', 'videos')\n```\n\nRetrieve a specific Document using its `id` or `external_id`:\n\n```ruby\ndocument = client.document('site-search-api-example', 'videos', 'FHtvDA0W34I')\n```\n\nTo create or update. single or multiple documents, we use the method `index_documents`.\n\nCreate a new Document with mandatory `external_id` and user-defined fields:\n\n```ruby\ndocument = client.index_documents('site-search-api-example', 'videos', {\n    :external_id =\u003e 'FHtvDA0W34I',\n    :fields =\u003e [\n        {:name =\u003e 'title', :value =\u003e \"Felix Baumgartner's supersonic freefall from 128k' - Mission Highlights\", :type =\u003e 'string'},\n        {:name =\u003e 'url', :value =\u003e 'http://www.youtube.com/watch?v=FHtvDA0W34I', :type =\u003e 'enum'},\n        {:name =\u003e 'chanel_id', :value =\u003e 'UCblfuW_4rakIf2h6aqANefA', :type =\u003e 'enum'}\n    ]})\n```\n\nCreate multiple Documents at once and return status for each Document creation:\n\n```ruby\nresponse = client.index_documents('site-search-api-example', 'videos', [{\n    :external_id =\u003e 'FHtvDA0W34I',\n    :fields =\u003e [\n        {:name =\u003e 'title', :value =\u003e \"Felix Baumgartner's supersonic freefall from 128k' - Mission Highlights\", :type =\u003e 'string'},\n        {:name =\u003e 'url', :value =\u003e 'http://www.youtube.com/watch?v=FHtvDA0W34I', :type =\u003e 'enum'},\n        {:name =\u003e 'chanel_id', :value =\u003e 'UCblfuW_4rakIf2h6aqANefA', :type =\u003e 'enum'}\n    ]}, {\n    :external_id =\u003e 'dMH0bHeiRNg',\n    :fields =\u003e [\n        {:name =\u003e 'title', :value =\u003e 'Evolution of Dance - By Judson Laipply', :type =\u003e 'string'},\n        {:name =\u003e 'url', :value =\u003e 'http://www.youtube.com/watch?v='dMH0bHeiRNg', :type =\u003e 'enum'},\n        {:name =\u003e 'chanel_id', :value =\u003e UC5B9H4l2vtgo7cAoExcFh-w', :type =\u003e 'enum'}\n    ]}])\n```\n\nUpdate fields of an existing Document specified by `id` or `external_id`:\n\n```ruby\nclient.index_documents('site-search-api-example', 'videos', 'FHtvDA0W34I', {:title =\u003e'New Title'})\n```\n\n**NOTE:** A field must already exist on a Document in order to update it.\n\nUpdate multiple Documents at once:\n\n```ruby\nresponse = client.index_documents('site-search-api-example','videos', [\n    {:external_id =\u003e 'FHtvDA0W34I', :fields =\u003e {:view_count =\u003e 32874417}},\n    {:external_id =\u003e 'dMH0bHeiRNg', :fields =\u003e {:view_count =\u003e 98323493}}\n])\n```\n\nAll methods above will have a return in the following format:\n\n```ruby\n    [\n      {\n        \"id\": \"5473d6142ed96065a9000001\",\n        \"external_id\": \"FHtvDA0W34I\",\n        \"status\": \"complete\",\n        \"errors\": [],\n        \"links\": {\n          \"receipt\": \"https://api.swiftype.com/api/v1/document_receipts/5473d6142ed96065a9000001.json\",\n          \"document\": \"https://api.swiftype.com/api/v1/engine/xyz/document_type/abc/document/5473d6142ed96065a9000001.json\"\n        }\n      },\n      {\n        \"id\": \"5473d6142ed96065a9000002\",\n        \"external_id\": \"dMH0bHeiRNg\",\n        \"status\": \"complete\",\n        \"errors\": [],\n        \"links\": {\n          \"receipt\": \"https://api.swiftype.com/api/v1/document_receipts/5473d6142ed96065a9000001.json\",\n          \"document\": \"https://api.swiftype.com/api/v1/engine/xyz/document_type/abc/document/5473d6142ed96065a9000002.json\"\n        }\n      }\n    ]\n```\n\n**NOTE:** If you'd like to create or update documents asynchronously, simply pass the option `:async =\u003e true` as the last argument.\n\nFor instance, to Create multiple Documents at once:\n\n```ruby\nresponse = client.index_documents('site-search-api-example', 'videos', [{\n    :external_id =\u003e 'FHtvDA0W34I',\n    :fields =\u003e [\n        {:name =\u003e 'title', :value =\u003e \"Felix Baumgartner's supersonic freefall from 128k' - Mission Highlights\", :type =\u003e 'string'},\n        {:name =\u003e 'url', :value =\u003e 'http://www.youtube.com/watch?v=FHtvDA0W34I', :type =\u003e 'enum'},\n        {:name =\u003e 'chanel_id', :value =\u003e 'UCblfuW_4rakIf2h6aqANefA', :type =\u003e 'enum'}\n    ]}, {\n    :external_id =\u003e 'dMH0bHeiRNg',\n    :fields =\u003e [\n        {:name =\u003e 'title', :value =\u003e 'Evolution of Dance - By Judson Laipply', :type =\u003e 'string'},\n        {:name =\u003e 'url', :value =\u003e 'http://www.youtube.com/watch?v='dMH0bHeiRNg', :type =\u003e 'enum'},\n        {:name =\u003e 'chanel_id', :value =\u003e UC5B9H4l2vtgo7cAoExcFh-w', :type =\u003e 'enum'}\n    ]}],\n    :async =\u003e true )\n    #=\u003e\n    # {\n    #     \"batch_link\": \"https://api.swiftype.com/api/v1/document_receipts.json?ids=5473d6142ed96065a9000001,5473d6142ed96065a9000002\",\n    #     \"document_receipts\": [\n    #     {\n    #         \"id\": \"5473d6142ed96065a9000001\",\n    #         \"external_id\": \"FHtvDA0W34I\",\n    #         \"status\": \"pending\",\n    #         \"errors\": [],\n    #         \"links\": {\n    #         \"receipt\": \"https://api.swiftype.com/api/v1/document_receipts/5473d6142ed96065a9000001.json\",\n    #         \"document\": null\n    #         }\n    #     },\n    #     {\n    #         \"id\": \"5473d6342ed96065a9000002\",\n    #         \"external_id\": \"dMH0bHeiRNg\",\n    #         \"status\": \"pending\",\n    #         \"errors\": [],\n    #         \"links\": {\n    #         \"receipt\": \"https://api.swiftype.com/api/v1/document_receipts/5473d6142ed96065a9000002.json\",\n    #         \"document\": null\n    #         }\n    #     }\n    #     ]\n    # }\n```\n\nTo check the status of documents with their document_receipt ids:\n\n```ruby\n    response = client.document_receipts([\"5473d6142ed96065a9000001\", \"5473d6342ed96065a9000002\"])\n    #=\u003e\n    # [\n    #   {\n    #     \"id\": \"5473d6142ed96065a9000001\",\n    #     \"external_id\": \"FHtvDA0W34I\",\n    #     \"status\": \"complete\",\n    #     \"errors\": [],\n    #     \"links\": {\n    #       \"receipt\": \"https://api.swiftype.com/api/v1/document_receipts/5473d6142ed96065a9000001.json\",\n    #       \"document\": \"https://api.swiftype.com/api/v1/engine/xyz/document_type/abc/document/5473d6142ed96065a9000001.json\"\n    #     }\n    #   },\n    #   {\n    #     \"id\": \"5473d6142ed96065a9000002\",\n    #     \"external_id\": \"dMH0bHeiRNg\",\n    #     \"status\": \"complete\",\n    #     \"errors\": [],\n    #     \"links\": {\n    #       \"receipt\": \"https://api.swiftype.com/api/v1/document_receipts/5473d6142ed96065a9000001.json\",\n    #       \"document\": \"https://api.swiftype.com/api/v1/engine/xyz/document_type/abc/document/5473d6142ed96065a9000002.json\"\n    #     }\n    #   }\n    # ]\n```\n\nDestroy a Document by external_id:\n\n```ruby\nclient.destroy_document('site-search-api-example','videos','dFs9WO2B8uI')\n```\n\nDestroy multiple Documents at once:\n\n```ruby\nresponse = client.destroy_documents('site-search-api-example', 'videos', ['QH2-TGUlwu4, 'v1uyQZNg2vE', 'ik5sdwYZ01Q'])\n#=\u003e [true, true, true]\n```\n\n### Domains\n\n**Domains** are a feature of crawler-based engines that represent a web site to index with the Swiftype web crawler.\n\nRetrieve all Domains of Engine `websites`:\n\n```ruby\ndomains = client.domains('websites')\n#=\u003e [{\"id\"=\u003e\"513fcc042ed960c186000001\", \"engine_id\"=\u003e\"513fcc042ed960114400000d\", \"submitted_url\"=\u003e\"http://example.com/\", \"start_crawl_url\"=\u003e\"http://www.example.com/\", \"crawling\"=\u003efalse, \"document_count\"=\u003e337, \"updated_at\"=\u003e\"2013-03-13T00:48:32Z\"}, ...]\n```\n\nRetrieve a specific Domain by `id`:\n\n```ruby\ndomain = client.domain('websites', '513fcc042ed960c186000001'')\n#=\u003e {\"id\"=\u003e\"513fcc042ed960c186000001\", \"engine_id\"=\u003e\"513fcc042ed960114400000d\", \"submitted_url\"=\u003e\"http://example.com/\", \"start_crawl_url\"=\u003e\"http://www.example.com/\", \"crawling\"=\u003efalse, \"document_count\"=\u003e337, \"updated_at\"=\u003e\"2013-03-13T00:48:32Z\"}\n```\n\nCreate a new Domain with the URL `https://swiftype.com` and start crawling:\n\n```ruby\ndomain = client.create_domain('websites', 'https://swiftype.com')\n```\n\nDelete a Domain using its `id`:\n\n```ruby\nclient.destroy_domain('websites', '513fcc042ed960c186000001')\n```\n\nInitiate a recrawl of a specific Domain using its `id`:\n\n```ruby\nclient.recrawl_domain('websites', '513fcc042ed960c186000001')\n```\n\nAdd or update a URL for a Domain:\n\n```ruby\nclient.crawl_url('websites', '513fcc042ed960c186000001', 'https://swiftype.com/new/path.html')\n```\n\n### Analytics\n\nSite Search records the number of searches, autoselects (when a user clicks a link from a suggest result), and clickthroughs (when a user clicks through to an item from a search result list. You can view this information in your Site Search Dashboard, but you can also export it using the API.\n\nTo get the number of searches per day from an Engine in the last 14 days:\n\n```ruby\nsearches = client.analytics_searches('site-search-api-example')\n#=\u003e [['2013-09-13', '123'], [2013-09-12', '94'], ... ]\n```\n\nYou can also use a specific start and/or end date:\n\n```ruby\nsearches = client.analytics_searches('site-search-api-example', {:start_date =\u003e '2013-01-01', :end_date =\u003e '2013-01-07'})\n```\n\nTo get the number of autoselects in the past 14 days:\n\n```ruby\nautoselects = client.analytics_autoselects('site-search-api-example')\n```\n\nAs with searches you can also limit by start and/or end date:\n\n```ruby\nautoselects = client.analytics_autoselects('site-search-api-example', {:start_date =\u003e '2013-01-01', :end_date =\u003e '2013-01-07'})\n```\n\nIf you are interested in the top queries for your Engine you can use:\n\n```ruby\ntop_queries = client.analytics_top_queries('site-search-api-example')\n# =\u003e [['query term', 123], ['another query', 121], ['yet another query', 92], ...]\n```\n\nTo see more top queries you can paginate through them using:\n\n```ruby\ntop_queries = client.analytics_top_queries('site-search-api-example', {:page =\u003e 2})\n```\n\nOr you can get the top queries in a specific date range:\n\n```ruby\ntop_queries = client.analytics_top_queries('site-search-api-example', {:start_date =\u003e '2013-01-01', :end_date =\u003e '2013-01-07'})\n```\n\nIf you want to improve you search results, you should always have a look at search queries, that return no results and perhaps add some Documents that match for this query or use our pining feature to add Documents for this query:\n\n```ruby\ntop_no_result_queries = client.analytics_top_no_result_queries('site-search-api-example')\n```\n\nYou can also specifiy a date range for queries without results:\n\n```ruby\ntop_no_result_queries = client.analytics_top_no_result_queries('site-search-api-example', {:start_date =\u003e '2013-01-01', :end_date =\u003e '2013-01-07'})\n```\n\n## Development\n\nYou can run tests with `rspec`.\n\nAll HTTP interactions are stubbed out using VCR.\n\n## FAQ 🔮\n\n### Where do I report issues with the client?\n\nIf something is not working as expected, please open an [issue](https://github.com/elastic/site-search-ruby/issues/new).\n\n### Where can I learn more about Site Search?\n\nYour best bet is to read the [documentation](https://swiftype.com/documentation/site-search).\n\n### Where else can I go to get help?\n\nYou can checkout the [Elastic Site Search community discuss forums](https://discuss.elastic.co/c/site-search).\n\n## Contribute 🚀\n\nWe welcome contributors to the project. Before you begin, a couple notes...\n\n- Before opening a pull request, please create an issue to [discuss the scope of your proposal](https://github.com/elastic/site-search-ruby/issues).\n- Please write simple code and concise documentation, when appropriate.\n\n## License 📗\n\n[Apache 2.0](https://github.com/elastic/site-search-ruby/blob/master/LICENSE.txt) © [Elastic](https://github.com/elastic)\n\nThank you to all the [contributors](https://github.com/elastic/site-search-ruby/graphs/contributors)!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felastic%2Fsite-search-ruby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felastic%2Fsite-search-ruby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felastic%2Fsite-search-ruby/lists"}