检索多个文档

像Elasticsearch一样,检索多个文档依旧非常快。合并多个请求可以避免每个请求单独的网络开销。如果你需要从Elasticsearch中检索多个文档,相对于一个一个的检索,更快的方式是在一个请求中使用multi-get或者mget API。

mget API参数是一个docs数组,数组的每个节点定义一个文档的_index_type_id元数据。如果你只想检索一个或几个确定的字段,也可以定义一个_source参数:

  1. POST /_mget
  2. {
  3. "docs" : [
  4. {
  5. "_index" : "website",
  6. "_type" : "blog",
  7. "_id" : 2
  8. },
  9. {
  10. "_index" : "website",
  11. "_type" : "pageviews",
  12. "_id" : 1,
  13. "_source": "views"
  14. }
  15. ]
  16. }

响应体也包含一个docs数组,每个文档还包含一个响应,它们按照请求定义的顺序排列。每个这样的响应与单独使用get request响应体相同:

  1. {
  2. "docs" : [
  3. {
  4. "_index" : "website",
  5. "_id" : "2",
  6. "_type" : "blog",
  7. "found" : true,
  8. "_source" : {
  9. "text" : "This is a piece of cake...",
  10. "title" : "My first external blog entry"
  11. },
  12. "_version" : 10
  13. },
  14. {
  15. "_index" : "website",
  16. "_id" : "1",
  17. "_type" : "pageviews",
  18. "found" : true,
  19. "_version" : 2,
  20. "_source" : {
  21. "views" : 2
  22. }
  23. }
  24. ]
  25. }

如果你想检索的文档在同一个_index中(甚至在同一个_type中),你就可以在URL中定义一个默认的/_index或者/_index/_type

你依旧可以在单独的请求中使用这些值:

  1. POST /website/blog/_mget
  2. {
  3. "docs" : [
  4. { "_id" : 2 },
  5. { "_type" : "pageviews", "_id" : 1 }
  6. ]
  7. }

事实上,如果所有文档具有相同_index_type,你可以通过简单的ids数组来代替完整的docs数组:

  1. POST /website/blog/_mget
  2. {
  3. "ids" : [ "2", "1" ]
  4. }

注意到我们请求的第二个文档并不存在。我们定义了类型为blog,但是ID为1的文档类型为pageviews。这个不存在的文档会在响应体中被告知。

  1. {
  2. "docs" : [
  3. {
  4. "_index" : "website",
  5. "_type" : "blog",
  6. "_id" : "2",
  7. "_version" : 10,
  8. "found" : true,
  9. "_source" : {
  10. "title": "My first external blog entry",
  11. "text": "This is a piece of cake..."
  12. }
  13. },
  14. {
  15. "_index" : "website",
  16. "_type" : "blog",
  17. "_id" : "1",
  18. "found" : false <1>
  19. }
  20. ]
  21. }
  • <1> 这个文档不存在

事实上第二个文档不存在并不影响第一个文档的检索。每个文档的检索和报告都是独立的。

注意:

尽管前面提到有一个文档没有被找到,但HTTP请求状态码还是200。事实上,就算所有文档都找不到,请求也还是返回200,原因是mget请求本身成功了。如果想知道每个文档是否都成功了,你需要检查found标志。