【发布时间】:2016-10-19 10:50:56
【问题描述】:
我在item 是parent 和user_items 是children 的儿童-父母关系上使用这种映射(嗯,它是一个缩短版本,以使问题更容易) .
curl -XPUT 'localhost:9200/myindex?pretty=true' -d '{
"mappings": {
"items": {
"dynamic": "strict",
"properties" : {
"title" : { "type": "string" },
"body" : { "type": "string" },
}},
"user_items": {
"dynamic": "strict",
"_parent": {"type": "items" },
"properties" : {
"user_id" : { "type": "integer" },
"source_id" : { "type": "integer" },
}}}}'
以及我通常进行的查询类型:
curl -XGET 'localhost:9200/myindex/items/_search?pretty=true' -d '{
"query": {
"bool": {
"must": [
{
"query_string": {
"fields": ["title", "body"],
"query": "mercado"
}
},
{
"has_child": {
"type": "user_items",
"query": {
"term": {
"user_id": 655
}}}}]}}}'
在此查询中,它必须在字段 title 和 body 上搜索给定 mercado 上的字符串 user_id,在本例中为 655。
第一个查询速度非常慢,最多可能需要 15 秒。以下是相当快的(
我读到第一个查询这么慢的原因是它被缓存了,然后其余的查询很快,因为它适用于缓存的内容。
我读到我可以使用"loading" : "eager" 来提升第一个查询。所以我在一个名为myindex_new 的新索引上创建了一个新映射
{
"mappings": {
"items": {
"dynamic": "strict",
"properties" : {
"title" : { "type": "string" ,
"fielddata": {
"loading" : "eager"}},
"body" : { "type": "string",
"fielddata": {
"loading" : "eager"}},
}},
"user_items": {
"dynamic": "strict",
"_parent": {"type": "items" },
"properties" : {
"user_id" : { "type": "integer" },
"source_id" : { "type": "integer" },
}}}}'
...并将所有内容重新索引如下:
curl -XPOST 'localhost:9200/_reindex' -d '{
"source" : {
"index" : "myindex"
},
"dest" : {
"index" : "myindex_new"
}
}'
问题是我没有得到更好的结果。如果我查询带有eager 的新索引,第一个查询仍然很慢。我还尝试在子字段上添加eager,但它仍然很慢。
我必须做出一些不同的事情吗?我在重新索引上做错了什么?
提前致谢!
【问题讨论】:
-
弹性搜索 2.3
-
Fielddata 用于对这些特定字段进行排序和聚合。它对您的特定查询没有帮助,因为您不使用这些字段进行排序或内部聚合。我会尝试不同类型的急切加载,而不是父字段:
"loading": "eager_global_ordinals"。更完整的例子here。另外,不要忘记过滤器缓存也起作用:-)。 -
Parent-child uses global ordinals to speed up joins.全局序号有两个用途:您在链接中引用的一个和我在链接中引用的一个。我指的是用于父级与其子级之间连接(如内部连接)的全局序数类型。你认为 ES 如何处理has_child部分?它在父母和孩子之间使用内存中的连接。对于这些连接,使用全局序数。它们需要构建和预加载。我的建议是按照该链接中的说明进行预加载。 -
正如我已经提到的,这并不是唯一反映第一次查询响应时间增加的事情。您还有未预加载的查询缓存。根据每种查询类型,根据一系列优化自动缓存查询。
-
对于这个特定的查询,您不需要它。我可以删除它们。
标签: elasticsearch