使用inner_hits时指定要为ElasticSearch查询返回的结果的总大小

时间:2015-09-21 19:55:28

标签: elasticsearch

ElasticSearch允许inner_hits指定'来自'和'尺寸'参数,搜索的外部请求主体也可以。

例如,假设我的索引包含25本书,每本书少于50章。下面的代码片段将返回所有书籍中的所有章节,因为“' size' 100本书包括所有25本书和一个'大小'共50章包括所有"少于50章":

        "index": 'books',
        "type": 'book',
        "body": {
          "from" : 0, "size" : 100, // outer hits, or books
          "query": {
              "filtered": {
                "filter": {
                  "nested": {
                    "inner_hits": {
                      "size": 50 // inner hits, or chapters
                    },
                    "path": "chapter",
                    "query": { "match_all": { } }, 
                  }
                }
               }
            },
            .
            .
            .

现在,我想用这样的场景实现分页。我的问题是,如何?

在这种情况下,我是否必须从搜索查询中返回上述最多100 * 50 = 5000个文档,并通过仅显示我感兴趣的切片在应用程序级别实现分页?或者,有没有办法在搜索查询本身中指定要返回的匹配总数,与内部/外部大小无关?

我在看"回应"如下所示,因此希望这些数据能够被分页:

        response.hits.hits.forEach(function(book) {
           chapters = book.inner_hits.chapters.hits.hits;

           chapters.forEach(function(chapter) {
               // ... this is one displayed result ...
           });
        });

2 个答案:

答案 0 :(得分:4)

我认为Elasticsearch和nested字段无法实现这一点。您看到结果的方式是正确的:ES分页并返回books它没有在nested inner_hits 内看到。不是它的工作原理。您需要在代码中手动处理分页。

另一个选项,但您需要 parent/child relationship而不是nested

然后,您可以查询子项(意思,章节)并对结果进行分页(章节)。您可以使用inner_hits并返回parent(图书本身)。

PUT /library
{
  "mappings": {
    "book": {
      "properties": {
        "name": {
          "type": "string"
        }
      }
    },
    "chapter": {
      "_parent": {
        "type": "book"
      },
      "properties": {
        "title": {
          "type": "string"
        }
      }
    }
  }
}

查询:

GET /library/chapter/_search
{
  "size": 5, 
  "query": {
    "has_parent": {
      "type": "book",
      "query": {
        "match_all": {}
      },
      "inner_hits" : {}
    }
  }
}

示例输出(修剪完整示例here):

  "hits": [
     {
        "_index": "library",
        "_type": "chapter",
        "_id": "1",
        "_score": 1,
        "_source": {
           "title": "chap1"
        },
        "inner_hits": {
           "book": {
              "hits": {
                 "total": 1,
                 "max_score": 1,
                 "hits": [
                    {
                       "_index": "library",
                       "_type": "book",
                       "_id": "book1",
                       "_score": 1,
                       "_source": {
                          "name": "book1"
                       }
                    }
                 ]
              }
           }
        }
     },
     {
        "_index": "library",
        "_type": "chapter",
        "_id": "2",
        "_score": 1,
        "_source": {
           "title": "chap2"
        },
        "inner_hits": {
           "book": {
              "hits": {
                 "total": 1,
                 "max_score": 1,
                 "hits": [
                    {
                       "_index": "library",
                       "_type": "book",
                       "_id": "book1",
                       "_score": 1,
                       "_source": {
                          "name": "book1"
                       }
                    }
                 ]
              }
           }
        }
     }

答案 1 :(得分:0)

搜索API允许添加某些标准参数,这些参数列在以下文档中:https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/api-reference-2-0.html#api-search-2-0

根据文件:

  

大小数字 - 要返回的匹配数(默认值:10)

这会使您的请求类似:

    "size": 5000,
    "index": 'books',
    "type": 'book',
    "body": {