1
0

getting-started.asciidoc 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983
  1. [[getting-started]]
  2. = Getting started with {es}
  3. [partintro]
  4. --
  5. Ready to take {es} for a test drive and see for yourself how you can use the
  6. REST APIs to store, search, and analyze data?
  7. Follow this getting started tutorial to:
  8. . Get an {es} cluster up and running
  9. . Index some sample documents
  10. . Search for documents using the {es} query language
  11. . Analyze the results using bucket and metrics aggregations
  12. Need more context?
  13. Check out the <<elasticsearch-intro,
  14. Elasticsearch Introduction>> to learn the lingo and understand the basics of
  15. how {es} works. If you're already familiar with {es} and want to see how it works
  16. with the rest of the stack, you might want to jump to the
  17. {stack-gs}/get-started-elastic-stack.html[Elastic Stack
  18. Tutorial] to see how to set up a system monitoring solution with {es}, {kib},
  19. {beats}, and {ls}.
  20. TIP: The fastest way to get started with {es} is to
  21. https://www.elastic.co/cloud/elasticsearch-service/signup[start a free 14-day
  22. trial of Elasticsearch Service] in the cloud.
  23. --
  24. [[getting-started-install]]
  25. == Get {es} up and running
  26. To take {es} for a test drive, you can create a one-click cloud deployment
  27. on the https://www.elastic.co/cloud/elasticsearch-service/signup[Elasticsearch Service],
  28. or <<run-elasticsearch-local, set up a multi-node {es} cluster>> on your own
  29. Linux, macOS, or Windows machine.
  30. [float]
  31. [[run-elasticsearch-local]]
  32. === Run {es} locally on Linux, macOS, or Windows
  33. When you create a cluster on the Elasticsearch Service, you automatically
  34. get a three-node cluster. By installing from the tar or zip archive, you can
  35. start multiple instances of {es} locally to see how a multi-node cluster behaves.
  36. To run a three-node {es} cluster locally:
  37. . Download the Elasticsearch archive for your OS:
  38. +
  39. Linux: https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-{version}-linux-x86_64.tar.gz[elasticsearch-{version}-linux-x86_64.tar.gz]
  40. +
  41. ["source","sh",subs="attributes,callouts"]
  42. --------------------------------------------------
  43. curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-{version}-linux-x86_64.tar.gz
  44. --------------------------------------------------
  45. // NOTCONSOLE
  46. +
  47. macOS: https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-{version}-darwin-x86_64.tar.gz[elasticsearch-{version}-darwin-x86_64.tar.gz]
  48. +
  49. ["source","sh",subs="attributes,callouts"]
  50. --------------------------------------------------
  51. curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-{version}-darwin-x86_64.tar.gz
  52. --------------------------------------------------
  53. // NOTCONSOLE
  54. +
  55. Windows:
  56. https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-{version}-windows-x86_64.zip[elasticsearch-{version}-windows-x86_64.zip]
  57. . Extract the archive:
  58. +
  59. Linux:
  60. +
  61. ["source","sh",subs="attributes,callouts"]
  62. --------------------------------------------------
  63. tar -xvf elasticsearch-{version}-linux-x86_64.tar.gz
  64. --------------------------------------------------
  65. +
  66. macOS:
  67. +
  68. ["source","sh",subs="attributes,callouts"]
  69. --------------------------------------------------
  70. tar -xvf elasticsearch-{version}-darwin-x86_64.tar.gz
  71. --------------------------------------------------
  72. +
  73. Windows PowerShell:
  74. +
  75. ["source","sh",subs="attributes,callouts"]
  76. --------------------------------------------------
  77. Expand-Archive elasticsearch-{version}-windows-x86_64.zip
  78. --------------------------------------------------
  79. . Start elasticsearch from the `bin` directory:
  80. +
  81. Linux and macOS:
  82. +
  83. ["source","sh",subs="attributes,callouts"]
  84. --------------------------------------------------
  85. cd elasticsearch-{version}/bin
  86. ./elasticsearch
  87. --------------------------------------------------
  88. +
  89. Windows:
  90. +
  91. ["source","sh",subs="attributes,callouts"]
  92. --------------------------------------------------
  93. cd %PROGRAMFILES%\Elastic\Elasticsearch\bin
  94. .\elasticsearch.exe
  95. --------------------------------------------------
  96. +
  97. You now have a single-node {es} cluster up and running!
  98. . Start two more instances of {es} so you can see how a typical multi-node
  99. cluster behaves. You need to specify unique data and log paths
  100. for each node.
  101. +
  102. Linux and macOS:
  103. +
  104. ["source","sh",subs="attributes,callouts"]
  105. --------------------------------------------------
  106. ./elasticsearch -Epath.data=data2 -Epath.logs=log2
  107. ./elasticsearch -Epath.data=data3 -Epath.logs=log3
  108. --------------------------------------------------
  109. +
  110. Windows:
  111. +
  112. ["source","sh",subs="attributes,callouts"]
  113. --------------------------------------------------
  114. .\elasticsearch.exe -Epath.data=data2 -Epath.logs=log2
  115. .\elasticsearch.exe -Epath.data=data3 -Epath.logs=log3
  116. --------------------------------------------------
  117. +
  118. The additional nodes are assigned unique IDs. Because you're running all three
  119. nodes locally, they automatically join the cluster with the first node.
  120. . Use the `cat health` API to verify that your three-node cluster is up running.
  121. The `cat` APIs return information about your cluster and indices in a
  122. format that's easier to read than raw JSON.
  123. +
  124. You can interact directly with your cluster by submitting HTTP requests to
  125. the {es} REST API. Most of the examples in this guide enable you to copy the
  126. appropriate cURL command and submit the request to your local {es} instance from
  127. the command line. If you have Kibana installed and running, you can also
  128. open Kibana and submit requests through the Dev Console.
  129. +
  130. TIP: You'll want to check out the
  131. https://www.elastic.co/guide/en/elasticsearch/client/index.html[{es} language
  132. clients] when you're ready to start using {es} in your own applications.
  133. +
  134. [source,js]
  135. --------------------------------------------------
  136. GET /_cat/health?v
  137. --------------------------------------------------
  138. // CONSOLE
  139. +
  140. The response should indicate that the status of the _elasticsearch_ cluster
  141. is _green_ and it has three nodes:
  142. +
  143. [source,txt]
  144. --------------------------------------------------
  145. epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
  146. 1565052807 00:53:27 elasticsearch green 3 3 6 3 0 0 0 0 - 100.0%
  147. --------------------------------------------------
  148. // TESTRESPONSE[s/1565052807 00:53:27 elasticsearch/\\d+ \\d+:\\d+:\\d+ integTest/]
  149. // TESTRESPONSE[s/3 3 6 3/\\d+ \\d+ \\d+ \\d+/]
  150. // TESTRESPONSE[s/0 0 -/0 \\d+ -/]
  151. // TESTRESPONSE[non_json]
  152. +
  153. NOTE: The cluster status will remain yellow if you are only running a single
  154. instance of {es}. A single node cluster is fully functional, but data
  155. cannot be replicated to another node to provide resiliency. Replica shards must
  156. be available for the cluster status to be green. If the cluster status is red,
  157. some data is unavailable.
  158. [float]
  159. [[gs-other-install]]
  160. === Other installation options
  161. Installing {es} from an archive file enables you to easily install and run
  162. multiple instances locally so you can try things out. To run a single instance,
  163. you can run {es} in a Docker container, install {es} using the DEB or RPM
  164. packages on Linux, install using Homebrew on macOS, or install using the MSI
  165. package installer on Windows. See <<install-elasticsearch>> for more information.
  166. [[getting-started-index]]
  167. == Index some documents
  168. Once you have a cluster up and running, you're ready to index some data.
  169. There are a variety of ingest options for {es}, but in the end they all
  170. do the same thing: put JSON documents into an {es} index.
  171. You can do this directly with a simple POST request that identifies
  172. the index you want to add the document to and specifies one or more
  173. `"field": "value"` pairs in the request body:
  174. [source,js]
  175. --------------------------------------------------
  176. PUT /customer/_doc/1
  177. {
  178. "name": "John Doe"
  179. }
  180. --------------------------------------------------
  181. // CONSOLE
  182. This request automatically creates the _customer_ index if it doesn't already
  183. exist, adds a new document that has an ID of `1`, and stores and
  184. indexes the _name_ field.
  185. Since this is a new document, the response shows that the result of the
  186. operation was that version 1 of the document was created:
  187. [source,js]
  188. --------------------------------------------------
  189. {
  190. "_index" : "customer",
  191. "_type" : "_doc",
  192. "_id" : "1",
  193. "_version" : 1,
  194. "result" : "created",
  195. "_shards" : {
  196. "total" : 2,
  197. "successful" : 2,
  198. "failed" : 0
  199. },
  200. "_seq_no" : 26,
  201. "_primary_term" : 4
  202. }
  203. --------------------------------------------------
  204. // TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/]
  205. // TESTRESPONSE[s/"successful" : \d+/"successful" : $body._shards.successful/]
  206. // TESTRESPONSE[s/"_primary_term" : \d+/"_primary_term" : $body._primary_term/]
  207. The new document is available immediately from any node in the cluster.
  208. You can retrieve it with a GET request that specifies its document ID:
  209. [source,js]
  210. --------------------------------------------------
  211. GET /customer/_doc/1
  212. --------------------------------------------------
  213. // CONSOLE
  214. // TEST[continued]
  215. The response indicates that a document with the specified ID was found
  216. and shows the original source fields that were indexed.
  217. [source,js]
  218. --------------------------------------------------
  219. {
  220. "_index" : "customer",
  221. "_type" : "_doc",
  222. "_id" : "1",
  223. "_version" : 1,
  224. "_seq_no" : 26,
  225. "_primary_term" : 4,
  226. "found" : true,
  227. "_source" : {
  228. "name": "John Doe"
  229. }
  230. }
  231. --------------------------------------------------
  232. // TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ ]
  233. // TESTRESPONSE[s/"_primary_term" : \d+/"_primary_term" : $body._primary_term/]
  234. [float]
  235. [[getting-started-batch-processing]]
  236. === Batch processing
  237. In addition to being able to index, update, and delete individual documents, Elasticsearch also provides the ability to perform any of the above operations in batches using the {ref}/docs-bulk.html[`_bulk` API]. This functionality is important in that it provides a very efficient mechanism to do multiple operations as fast as possible with as few network roundtrips as possible.
  238. As a quick example, the following call indexes two documents (ID 1 - John Doe and ID 2 - Jane Doe) in one bulk operation:
  239. [source,js]
  240. --------------------------------------------------
  241. POST /customer/_bulk?pretty
  242. {"index":{"_id":"1"}}
  243. {"name": "John Doe" }
  244. {"index":{"_id":"2"}}
  245. {"name": "Jane Doe" }
  246. --------------------------------------------------
  247. // CONSOLE
  248. This example updates the first document (ID of 1) and then deletes the second document (ID of 2) in one bulk operation:
  249. [source,sh]
  250. --------------------------------------------------
  251. POST /customer/_bulk
  252. {"update":{"_id":"1"}}
  253. {"doc": { "name": "John Doe becomes Jane Doe" } }
  254. {"delete":{"_id":"2"}}
  255. --------------------------------------------------
  256. // CONSOLE
  257. // TEST[continued]
  258. Note above that for the delete action, there is no corresponding source document after it since deletes only require the ID of the document to be deleted.
  259. The Bulk API does not fail due to failures in one of the actions. If a single action fails for whatever reason, it will continue to process the remainder of the actions after it. When the bulk API returns, it will provide a status for each action (in the same order it was sent in) so that you can check if a specific action failed or not.
  260. [float]
  261. === Sample dataset
  262. Now that we've gotten a glimpse of the basics, let's try to work on a more realistic dataset. I've prepared a sample of fictitious JSON documents of customer bank account information. Each document has the following schema:
  263. [source,js]
  264. --------------------------------------------------
  265. {
  266. "account_number": 0,
  267. "balance": 16623,
  268. "firstname": "Bradshaw",
  269. "lastname": "Mckenzie",
  270. "age": 29,
  271. "gender": "F",
  272. "address": "244 Columbus Place",
  273. "employer": "Euron",
  274. "email": "bradshawmckenzie@euron.com",
  275. "city": "Hobucken",
  276. "state": "CO"
  277. }
  278. --------------------------------------------------
  279. // NOTCONSOLE
  280. For the curious, this data was generated using http://www.json-generator.com/[`www.json-generator.com/`], so please ignore the actual values and semantics of the data as these are all randomly generated.
  281. You can download the sample dataset (accounts.json) from https://github.com/elastic/elasticsearch/blob/master/docs/src/test/resources/accounts.json?raw=true[here]. Extract it to our current directory and let's load it into our cluster as follows:
  282. [source,sh]
  283. --------------------------------------------------
  284. curl -H "Content-Type: application/json" -XPOST "localhost:9200/bank/_bulk?pretty&refresh" --data-binary "@accounts.json"
  285. curl "localhost:9200/_cat/indices?v"
  286. --------------------------------------------------
  287. // NOTCONSOLE
  288. ////
  289. This replicates the above in a document-testing friendly way but isn't visible
  290. in the docs:
  291. [source,js]
  292. --------------------------------------------------
  293. GET /_cat/indices?v
  294. --------------------------------------------------
  295. // CONSOLE
  296. // TEST[setup:bank]
  297. ////
  298. And the response:
  299. [source,txt]
  300. --------------------------------------------------
  301. health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
  302. yellow open bank l7sSYV2cQXmu6_4rJWVIww 5 1 1000 0 128.6kb 128.6kb
  303. --------------------------------------------------
  304. // TESTRESPONSE[s/128.6kb/\\d+(\\.\\d+)?[mk]?b/]
  305. // TESTRESPONSE[s/l7sSYV2cQXmu6_4rJWVIww/.+/ non_json]
  306. Which means that we just successfully bulk indexed 1000 documents into the bank index.
  307. [[getting-started-search]]
  308. == Start searching
  309. Now let's start with some simple searches. There are two basic ways to run searches: one is by sending search parameters through the {ref}/search-uri-request.html[REST request URI] and the other by sending them through the {ref}/search-request-body.html[REST request body]. The request body method allows you to be more expressive and also to define your searches in a more readable JSON format. We'll try one example of the request URI method but for the remainder of this tutorial, we will exclusively be using the request body method.
  310. The REST API for search is accessible from the `_search` endpoint. This example returns all documents in the bank index:
  311. [source,js]
  312. --------------------------------------------------
  313. GET /bank/_search?q=*&sort=account_number:asc&pretty
  314. --------------------------------------------------
  315. // CONSOLE
  316. // TEST[continued]
  317. Let's first dissect the search call. We are searching (`_search` endpoint) in the bank index, and the `q=*` parameter instructs Elasticsearch to match all documents in the index. The `sort=account_number:asc` parameter indicates to sort the results using the `account_number` field of each document in an ascending order. The `pretty` parameter, again, just tells Elasticsearch to return pretty-printed JSON results.
  318. And the response (partially shown):
  319. [source,js]
  320. --------------------------------------------------
  321. {
  322. "took" : 63,
  323. "timed_out" : false,
  324. "_shards" : {
  325. "total" : 5,
  326. "successful" : 5,
  327. "skipped" : 0,
  328. "failed" : 0
  329. },
  330. "hits" : {
  331. "total" : {
  332. "value": 1000,
  333. "relation": "eq"
  334. },
  335. "max_score" : null,
  336. "hits" : [ {
  337. "_index" : "bank",
  338. "_type" : "_doc",
  339. "_id" : "0",
  340. "sort": [0],
  341. "_score" : null,
  342. "_source" : {"account_number":0,"balance":16623,"firstname":"Bradshaw","lastname":"Mckenzie","age":29,"gender":"F","address":"244 Columbus Place","employer":"Euron","email":"bradshawmckenzie@euron.com","city":"Hobucken","state":"CO"}
  343. }, {
  344. "_index" : "bank",
  345. "_type" : "_doc",
  346. "_id" : "1",
  347. "sort": [1],
  348. "_score" : null,
  349. "_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
  350. }, ...
  351. ]
  352. }
  353. }
  354. --------------------------------------------------
  355. // TESTRESPONSE[s/"took" : 63/"took" : $body.took/]
  356. // TESTRESPONSE[s/\.\.\./$body.hits.hits.2, $body.hits.hits.3, $body.hits.hits.4, $body.hits.hits.5, $body.hits.hits.6, $body.hits.hits.7, $body.hits.hits.8, $body.hits.hits.9/]
  357. As for the response, we see the following parts:
  358. * `took` – time in milliseconds for Elasticsearch to execute the search
  359. * `timed_out` – tells us if the search timed out or not
  360. * `_shards` – tells us how many shards were searched, as well as a count of the successful/failed searched shards
  361. * `hits` – search results
  362. * `hits.total` – an object that contains information about the total number of documents matching our search criteria
  363. ** `hits.total.value` - the value of the total hit count (must be interpreted in the context of `hits.total.relation`).
  364. ** `hits.total.relation` - whether `hits.total.value` is the exact hit count, in which case it is equal to `"eq"` or a
  365. lower bound of the total hit count (greater than or equals), in which case it is equal to `gte`.
  366. * `hits.hits` – actual array of search results (defaults to first 10 documents)
  367. * `hits.sort` - sort value of the sort key for each result (missing if sorting by score)
  368. * `hits._score` and `max_score` - ignore these fields for now
  369. The accuracy of `hits.total` is controlled by the request parameter `track_total_hits`, when set to true
  370. the request will track the total hits accurately (`"relation": "eq"`). It defaults to `10,000`
  371. which means that the total hit count is accurately tracked up to `10,000` documents.
  372. You can force an accurate count by setting `track_total_hits` to true explicitly.
  373. See the <<request-body-search-track-total-hits, request body>> documentation
  374. for more details.
  375. Here is the same exact search above using the alternative request body method:
  376. [source,js]
  377. --------------------------------------------------
  378. GET /bank/_search
  379. {
  380. "query": { "match_all": {} },
  381. "sort": [
  382. { "account_number": "asc" }
  383. ]
  384. }
  385. --------------------------------------------------
  386. // CONSOLE
  387. // TEST[continued]
  388. The difference here is that instead of passing `q=*` in the URI, we provide a JSON-style query request body to the `_search` API. We'll discuss this JSON query in the next section.
  389. ////
  390. Hidden response just so we can assert that it is indeed the same but don't have
  391. to clutter the docs with it:
  392. [source,js]
  393. --------------------------------------------------
  394. {
  395. "took" : 63,
  396. "timed_out" : false,
  397. "_shards" : {
  398. "total" : 5,
  399. "successful" : 5,
  400. "skipped" : 0,
  401. "failed" : 0
  402. },
  403. "hits" : {
  404. "total" : {
  405. "value": 1000,
  406. "relation": "eq"
  407. },
  408. "max_score": null,
  409. "hits" : [ {
  410. "_index" : "bank",
  411. "_type" : "_doc",
  412. "_id" : "0",
  413. "sort": [0],
  414. "_score": null,
  415. "_source" : {"account_number":0,"balance":16623,"firstname":"Bradshaw","lastname":"Mckenzie","age":29,"gender":"F","address":"244 Columbus Place","employer":"Euron","email":"bradshawmckenzie@euron.com","city":"Hobucken","state":"CO"}
  416. }, {
  417. "_index" : "bank",
  418. "_type" : "_doc",
  419. "_id" : "1",
  420. "sort": [1],
  421. "_score": null,
  422. "_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
  423. }, ...
  424. ]
  425. }
  426. }
  427. --------------------------------------------------
  428. // TESTRESPONSE[s/"took" : 63/"took" : $body.took/]
  429. // TESTRESPONSE[s/\.\.\./$body.hits.hits.2, $body.hits.hits.3, $body.hits.hits.4, $body.hits.hits.5, $body.hits.hits.6, $body.hits.hits.7, $body.hits.hits.8, $body.hits.hits.9/]
  430. ////
  431. It is important to understand that once you get your search results back, Elasticsearch is completely done with the request and does not maintain any kind of server-side resources or open cursors into your results. This is in stark contrast to many other platforms such as SQL wherein you may initially get a partial subset of your query results up-front and then you have to continuously go back to the server if you want to fetch (or page through) the rest of the results using some kind of stateful server-side cursor.
  432. [float]
  433. [[getting-started-query-lang]]
  434. === Introducing the Query Language
  435. Elasticsearch provides a JSON-style domain-specific language that you can use to execute queries. This is referred to as the {ref}/query-dsl.html[Query DSL]. The query language is quite comprehensive and can be intimidating at first glance but the best way to actually learn it is to start with a few basic examples.
  436. Going back to our last example, we executed this query:
  437. [source,js]
  438. --------------------------------------------------
  439. GET /bank/_search
  440. {
  441. "query": { "match_all": {} }
  442. }
  443. --------------------------------------------------
  444. // CONSOLE
  445. // TEST[continued]
  446. Dissecting the above, the `query` part tells us what our query definition is and the `match_all` part is simply the type of query that we want to run. The `match_all` query is simply a search for all documents in the specified index.
  447. In addition to the `query` parameter, we also can pass other parameters to
  448. influence the search results. In the example in the section above we passed in
  449. `sort`, here we pass in `size`:
  450. [source,js]
  451. --------------------------------------------------
  452. GET /bank/_search
  453. {
  454. "query": { "match_all": {} },
  455. "size": 1
  456. }
  457. --------------------------------------------------
  458. // CONSOLE
  459. // TEST[continued]
  460. Note that if `size` is not specified, it defaults to 10.
  461. This example does a `match_all` and returns documents 10 through 19:
  462. [source,js]
  463. --------------------------------------------------
  464. GET /bank/_search
  465. {
  466. "query": { "match_all": {} },
  467. "from": 10,
  468. "size": 10
  469. }
  470. --------------------------------------------------
  471. // CONSOLE
  472. // TEST[continued]
  473. The `from` parameter (0-based) specifies which document index to start from and the `size` parameter specifies how many documents to return starting at the from parameter. This feature is useful when implementing paging of search results. Note that if `from` is not specified, it defaults to 0.
  474. This example does a `match_all` and sorts the results by account balance in descending order and returns the top 10 (default size) documents.
  475. [source,js]
  476. --------------------------------------------------
  477. GET /bank/_search
  478. {
  479. "query": { "match_all": {} },
  480. "sort": { "balance": { "order": "desc" } }
  481. }
  482. --------------------------------------------------
  483. // CONSOLE
  484. // TEST[continued]
  485. Now that we have seen a few of the basic search parameters, let's dig in some more into the Query DSL. Let's first take a look at the returned document fields. By default, the full JSON document is returned as part of all searches. This is referred to as the source (`_source` field in the search hits). If we don't want the entire source document returned, we have the ability to request only a few fields from within source to be returned.
  486. This example shows how to return two fields, `account_number` and `balance` (inside of `_source`), from the search:
  487. [source,js]
  488. --------------------------------------------------
  489. GET /bank/_search
  490. {
  491. "query": { "match_all": {} },
  492. "_source": ["account_number", "balance"]
  493. }
  494. --------------------------------------------------
  495. // CONSOLE
  496. // TEST[continued]
  497. Note that the above example simply reduces the `_source` field. It will still only return one field named `_source` but within it, only the fields `account_number` and `balance` are included.
  498. If you come from a SQL background, the above is somewhat similar in concept to the `SQL SELECT FROM` field list.
  499. Now let's move on to the query part. Previously, we've seen how the `match_all` query is used to match all documents. Let's now introduce a new query called the {ref}/query-dsl-match-query.html[`match` query], which can be thought of as a basic fielded search query (i.e. a search done against a specific field or set of fields).
  500. This example returns the account numbered 20:
  501. [source,js]
  502. --------------------------------------------------
  503. GET /bank/_search
  504. {
  505. "query": { "match": { "account_number": 20 } }
  506. }
  507. --------------------------------------------------
  508. // CONSOLE
  509. // TEST[continued]
  510. This example returns all accounts containing the term "mill" in the address:
  511. [source,js]
  512. --------------------------------------------------
  513. GET /bank/_search
  514. {
  515. "query": { "match": { "address": "mill" } }
  516. }
  517. --------------------------------------------------
  518. // CONSOLE
  519. // TEST[continued]
  520. This example returns all accounts containing the term "mill" or "lane" in the address:
  521. [source,js]
  522. --------------------------------------------------
  523. GET /bank/_search
  524. {
  525. "query": { "match": { "address": "mill lane" } }
  526. }
  527. --------------------------------------------------
  528. // CONSOLE
  529. // TEST[continued]
  530. This example is a variant of `match` (`match_phrase`) that returns all accounts containing the phrase "mill lane" in the address:
  531. [source,js]
  532. --------------------------------------------------
  533. GET /bank/_search
  534. {
  535. "query": { "match_phrase": { "address": "mill lane" } }
  536. }
  537. --------------------------------------------------
  538. // CONSOLE
  539. // TEST[continued]
  540. Let's now introduce the {ref}/query-dsl-bool-query.html[`bool` query]. The `bool` query allows us to compose smaller queries into bigger queries using boolean logic.
  541. This example composes two `match` queries and returns all accounts containing "mill" and "lane" in the address:
  542. [source,js]
  543. --------------------------------------------------
  544. GET /bank/_search
  545. {
  546. "query": {
  547. "bool": {
  548. "must": [
  549. { "match": { "address": "mill" } },
  550. { "match": { "address": "lane" } }
  551. ]
  552. }
  553. }
  554. }
  555. --------------------------------------------------
  556. // CONSOLE
  557. // TEST[continued]
  558. In the above example, the `bool must` clause specifies all the queries that must be true for a document to be considered a match.
  559. In contrast, this example composes two `match` queries and returns all accounts containing "mill" or "lane" in the address:
  560. [source,js]
  561. --------------------------------------------------
  562. GET /bank/_search
  563. {
  564. "query": {
  565. "bool": {
  566. "should": [
  567. { "match": { "address": "mill" } },
  568. { "match": { "address": "lane" } }
  569. ]
  570. }
  571. }
  572. }
  573. --------------------------------------------------
  574. // CONSOLE
  575. // TEST[continued]
  576. In the above example, the `bool should` clause specifies a list of queries either of which must be true for a document to be considered a match.
  577. This example composes two `match` queries and returns all accounts that contain neither "mill" nor "lane" in the address:
  578. [source,js]
  579. --------------------------------------------------
  580. GET /bank/_search
  581. {
  582. "query": {
  583. "bool": {
  584. "must_not": [
  585. { "match": { "address": "mill" } },
  586. { "match": { "address": "lane" } }
  587. ]
  588. }
  589. }
  590. }
  591. --------------------------------------------------
  592. // CONSOLE
  593. // TEST[continued]
  594. In the above example, the `bool must_not` clause specifies a list of queries none of which must be true for a document to be considered a match.
  595. We can combine `must`, `should`, and `must_not` clauses simultaneously inside a `bool` query. Furthermore, we can compose `bool` queries inside any of these `bool` clauses to mimic any complex multi-level boolean logic.
  596. This example returns all accounts of anybody who is 40 years old but doesn't live in ID(aho):
  597. [source,js]
  598. --------------------------------------------------
  599. GET /bank/_search
  600. {
  601. "query": {
  602. "bool": {
  603. "must": [
  604. { "match": { "age": "40" } }
  605. ],
  606. "must_not": [
  607. { "match": { "state": "ID" } }
  608. ]
  609. }
  610. }
  611. }
  612. --------------------------------------------------
  613. // CONSOLE
  614. // TEST[continued]
  615. [float]
  616. [[getting-started-filters]]
  617. === Executing filters
  618. In the previous section, we skipped over a little detail called the document score (`_score` field in the search results). The score is a numeric value that is a relative measure of how well the document matches the search query that we specified. The higher the score, the more relevant the document is, the lower the score, the less relevant the document is.
  619. But queries do not always need to produce scores, in particular when they are only used for "filtering" the document set. Elasticsearch detects these situations and automatically optimizes query execution in order not to compute useless scores.
  620. The {ref}/query-dsl-bool-query.html[`bool` query] that we introduced in the previous section also supports `filter` clauses which allow us to use a query to restrict the documents that will be matched by other clauses, without changing how scores are computed. As an example, let's introduce the {ref}/query-dsl-range-query.html[`range` query], which allows us to filter documents by a range of values. This is generally used for numeric or date filtering.
  621. This example uses a bool query to return all accounts with balances between 20000 and 30000, inclusive. In other words, we want to find accounts with a balance that is greater than or equal to 20000 and less than or equal to 30000.
  622. [source,js]
  623. --------------------------------------------------
  624. GET /bank/_search
  625. {
  626. "query": {
  627. "bool": {
  628. "must": { "match_all": {} },
  629. "filter": {
  630. "range": {
  631. "balance": {
  632. "gte": 20000,
  633. "lte": 30000
  634. }
  635. }
  636. }
  637. }
  638. }
  639. }
  640. --------------------------------------------------
  641. // CONSOLE
  642. // TEST[continued]
  643. Dissecting the above, the bool query contains a `match_all` query (the query part) and a `range` query (the filter part). We can substitute any other queries into the query and the filter parts. In the above case, the range query makes perfect sense since documents falling into the range all match "equally", i.e., no document is more relevant than another.
  644. In addition to the `match_all`, `match`, `bool`, and `range` queries, there are a lot of other query types that are available and we won't go into them here. Since we already have a basic understanding of how they work, it shouldn't be too difficult to apply this knowledge in learning and experimenting with the other query types.
  645. [[getting-started-aggregations]]
  646. == Analyze results with aggregations
  647. Aggregations provide the ability to group and extract statistics from your data. The easiest way to think about aggregations is by roughly equating it to the SQL GROUP BY and the SQL aggregate functions. In Elasticsearch, you have the ability to execute searches returning hits and at the same time return aggregated results separate from the hits all in one response. This is very powerful and efficient in the sense that you can run queries and multiple aggregations and get the results back of both (or either) operations in one shot avoiding network roundtrips using a concise and simplified API.
  648. To start with, this example groups all the accounts by state, and then returns the top 10 (default) states sorted by count descending (also default):
  649. [source,js]
  650. --------------------------------------------------
  651. GET /bank/_search
  652. {
  653. "size": 0,
  654. "aggs": {
  655. "group_by_state": {
  656. "terms": {
  657. "field": "state.keyword"
  658. }
  659. }
  660. }
  661. }
  662. --------------------------------------------------
  663. // CONSOLE
  664. // TEST[continued]
  665. In SQL, the above aggregation is similar in concept to:
  666. [source,sh]
  667. --------------------------------------------------
  668. SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC LIMIT 10;
  669. --------------------------------------------------
  670. And the response (partially shown):
  671. [source,js]
  672. --------------------------------------------------
  673. {
  674. "took": 29,
  675. "timed_out": false,
  676. "_shards": {
  677. "total": 5,
  678. "successful": 5,
  679. "skipped" : 0,
  680. "failed": 0
  681. },
  682. "hits" : {
  683. "total" : {
  684. "value": 1000,
  685. "relation": "eq"
  686. },
  687. "max_score" : null,
  688. "hits" : [ ]
  689. },
  690. "aggregations" : {
  691. "group_by_state" : {
  692. "doc_count_error_upper_bound": 20,
  693. "sum_other_doc_count": 770,
  694. "buckets" : [ {
  695. "key" : "ID",
  696. "doc_count" : 27
  697. }, {
  698. "key" : "TX",
  699. "doc_count" : 27
  700. }, {
  701. "key" : "AL",
  702. "doc_count" : 25
  703. }, {
  704. "key" : "MD",
  705. "doc_count" : 25
  706. }, {
  707. "key" : "TN",
  708. "doc_count" : 23
  709. }, {
  710. "key" : "MA",
  711. "doc_count" : 21
  712. }, {
  713. "key" : "NC",
  714. "doc_count" : 21
  715. }, {
  716. "key" : "ND",
  717. "doc_count" : 21
  718. }, {
  719. "key" : "ME",
  720. "doc_count" : 20
  721. }, {
  722. "key" : "MO",
  723. "doc_count" : 20
  724. } ]
  725. }
  726. }
  727. }
  728. --------------------------------------------------
  729. // TESTRESPONSE[s/"took": 29/"took": $body.took/]
  730. We can see that there are 27 accounts in `ID` (Idaho), followed by 27 accounts
  731. in `TX` (Texas), followed by 25 accounts in `AL` (Alabama), and so forth.
  732. Note that we set `size=0` to not show search hits because we only want to see the aggregation results in the response.
  733. Building on the previous aggregation, this example calculates the average account balance by state (again only for the top 10 states sorted by count in descending order):
  734. [source,js]
  735. --------------------------------------------------
  736. GET /bank/_search
  737. {
  738. "size": 0,
  739. "aggs": {
  740. "group_by_state": {
  741. "terms": {
  742. "field": "state.keyword"
  743. },
  744. "aggs": {
  745. "average_balance": {
  746. "avg": {
  747. "field": "balance"
  748. }
  749. }
  750. }
  751. }
  752. }
  753. }
  754. --------------------------------------------------
  755. // CONSOLE
  756. // TEST[continued]
  757. Notice how we nested the `average_balance` aggregation inside the `group_by_state` aggregation. This is a common pattern for all the aggregations. You can nest aggregations inside aggregations arbitrarily to extract pivoted summarizations that you require from your data.
  758. Building on the previous aggregation, let's now sort on the average balance in descending order:
  759. [source,js]
  760. --------------------------------------------------
  761. GET /bank/_search
  762. {
  763. "size": 0,
  764. "aggs": {
  765. "group_by_state": {
  766. "terms": {
  767. "field": "state.keyword",
  768. "order": {
  769. "average_balance": "desc"
  770. }
  771. },
  772. "aggs": {
  773. "average_balance": {
  774. "avg": {
  775. "field": "balance"
  776. }
  777. }
  778. }
  779. }
  780. }
  781. }
  782. --------------------------------------------------
  783. // CONSOLE
  784. // TEST[continued]
  785. This example demonstrates how we can group by age brackets (ages 20-29, 30-39, and 40-49), then by gender, and then finally get the average account balance, per age bracket, per gender:
  786. [source,js]
  787. --------------------------------------------------
  788. GET /bank/_search
  789. {
  790. "size": 0,
  791. "aggs": {
  792. "group_by_age": {
  793. "range": {
  794. "field": "age",
  795. "ranges": [
  796. {
  797. "from": 20,
  798. "to": 30
  799. },
  800. {
  801. "from": 30,
  802. "to": 40
  803. },
  804. {
  805. "from": 40,
  806. "to": 50
  807. }
  808. ]
  809. },
  810. "aggs": {
  811. "group_by_gender": {
  812. "terms": {
  813. "field": "gender.keyword"
  814. },
  815. "aggs": {
  816. "average_balance": {
  817. "avg": {
  818. "field": "balance"
  819. }
  820. }
  821. }
  822. }
  823. }
  824. }
  825. }
  826. }
  827. --------------------------------------------------
  828. // CONSOLE
  829. // TEST[continued]
  830. There are many other aggregations capabilities that we won't go into detail here. The {ref}/search-aggregations.html[aggregations reference guide] is a great starting point if you want to do further experimentation.
  831. [[getting-started-next-steps]]
  832. == Where to go from here
  833. Now that you've set up a cluster, indexed some documents, and run some
  834. searches and aggregations, you might want to:
  835. * {stack-gs}/get-started-elastic-stack.html#install-kibana[Dive in to the Elastic
  836. Stack Tutorial] to install Kibana, Logstash, and Beats and
  837. set up a basic system monitoring solution.
  838. * {kibana-ref}/add-sample-data.html[Load one of the sample data sets into Kibana]
  839. to see how you can use {es} and Kibana together to visualize your data.
  840. * Try out one of the Elastic search solutions:
  841. ** https://swiftype.com/documentation/site-search/crawler-quick-start[Site Search]
  842. ** https://swiftype.com/documentation/app-search/getting-started[App Search]
  843. ** https://swiftype.com/documentation/enterprise-search/getting-started[Enterprise Search]