Elasticsearch:翻转后的父子关系

Elasticsearch: Parent-child relationship after rollover

假设有一个简单的博客索引,它包含两种类型:博客和评论。一个博客可以有多个评论。索引是这样创建的

curl -X PUT \
  'http://localhost:9200/%3Cblog-%7Bnow%2Fd%7D-000001%3E?pretty=' \
  -H 'content-type: application/json' \
  -d '{
    "mappings": {
        "comment": {
            "_parent": { "type": "blog" },
            "properties": { 
                "name": { "type": "keyword" },
                "comment": { "type": "text" }
            }
        },
        "blog": {
            "properties": {
                "author": { "type": "keyword" },
                "subject": { "type": "text" },
                "content": { "type": "text" }
            }
        }
    }
}'

索引 %3Cblog-%7Bnow%2Fd%7D-000001%3E 等于 <blog-{now/d}-000001>(有关日期数学的更多信息,请参阅 here)。 我们将向该索引添加 'blog-active' 别名。此别名将用于存储数据。

curl -X POST 'http://localhost:9200/_aliases?pretty=' \
  -H 'content-type: application/json' \
  -d '{ "actions" : [ { "add" : { "index" : "blog-*", "alias" : "blog-active" } } ] }'

现在,如果我们执行以下操作:

1.Add 博客使用 blog-active 别名

curl -X POST http://localhost:9200/blog-active/blog/1 \
  -H 'content-type: application/json' \
  -d '{
      "author": "author1",
      "subject": "subject1",
      "content": "content1"
  }'

2.Add 对博客发表评论

curl -X POST \
  'http://localhost:9200/blog-active/comment/1?parent=1' \
  -H 'content-type: application/json' \
  -d '{
  "name": "commenter1",
  "comment": "new comment1"
}'

3.Do 翻转 max_docs = 2

curl -X POST \
  http://localhost:9200/blog-active/_rollover \
  -H 'content-type: application/json' \
  -d '{
  "conditions": {
    "max_docs": 2
  },
  "mappings": {
    "comment": {
      "_parent": { "type": "blog" },
      "properties": {
        "name": { "type": "keyword" },
        "comment": { "type": "text" }
      }
    },
    "blog": {
      "properties": {
        "author": { "type": "keyword" },
        "subject": { "type": "text" },
        "content": { "type": "text" }
      }
    }
  }
}'

4.And 向博客添加另一条评论

curl -X POST \
  'http://localhost:9200/blog-active/comment/1?parent=1' \
  -H 'content-type: application/json' \
  -d '{
  "name": "commenter2",
  "comment": "new comment2"
}'

现在,如果我们在所有博客索引中搜索 'author1' 博客上的所有评论(blog-%2Ablog-*

curl -X POST \
  http://localhost:9200/blog-%2A/comment/_search \
  -H 'content-type: application/json' \
  -d '{
  "query": {
      "has_parent" : {
        "query" : {
          "match" : { "author" : { "query" : "author1" } }
        },
        "parent_type" : "blog"
      }
  }
}'

结果只包含第一条评论。

这是因为第二条评论在第二个索引中,它本身没有父博客文档。所以它不知道博客的作者。

那么,我的问题是在使用翻转时如何处理父子关系?

在那种情况下,这种关系甚至可能吗?

类似问题:ElasticSearch parent/child on different indexes

构成父子关系一部分的所有文档都需要存在于同一个索引中,更重要的是同一个分片。因此,如果使用翻转,则不可能有父子关系,因为它会创建新索引。

上述问题的一个解决方案是通过在 comment 类型中添加字段 blog_authorblog_id 来对数据进行非规范化。这种情况下的映射将如下所示(注意父子关系已被删除):

"mappings": {
  "comment": {
    "properties": {
      "blog_id": { "type": "keyword" },
      "blog_author": { "type": "keyword" },
      "name": { "type": "keyword" },
      "comment": { "type": "text" }
    }
  },
  "blog": {
    "properties": {
      "author": { "type": "keyword" },
      "subject": { "type": "text" },
      "content": { "type": "text" }
    }
  }
}

获取博客作者评论的查询是:

curl -X POST \
  http://localhost:9200/blog-%2A/comment/_search \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -d '{
  "query": {
    "match": {
        "blog_author": "user1"
    }
  }
}'