# 親ドキュメントの再帰的な取得方法について

**URL:** https://discuss.elastic.co/t/topic/177434
**Category:** 日本語による質問・議論はこちら
**Created:** [April 18, 2019, 9:51am UTC](https://discuss.elastic.co/t/topic/177434 "2019-04-18T09:51:17Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![onorioriori](https://avatars.discourse-cdn.com/v4/letter/o/74df32/32.png) [@onorioriori](https://discuss.elastic.co/u/onorioriori)
#### Post date: [April 18, 2019, 9:51am UTC](https://discuss.elastic.co/t/topic/177434/1 "2019-04-18T09:51:17Z")

</div>

`join` datatypeについて質問です。  
ドキュメントの親子関係が

- 子 a → b → c 親

というようになっており、今後も

- 子 a → b → c → d → e 親

のように増えていくことが考えられる場合に、  
その時点でのaの一番上の親(前者であればc, 後者であればe)を  
一度で取得するようなことは出来るのでしょうか？

やはりhas\_child queryなどを用いて、一番上の親が取得出来るまでループする必要があるのでしょうか？

イメージとしては

```auto
PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "my_join_field": {
          "type": "join",
          "relations": {
            "new": "old" 
          }
        }
      }
    }
  }
}

PUT my_index/_doc/c
{
  "my_join_field": {
    "name": "new"
  }
}

PUT my_index/_doc/b?routing=c
{
  "my_join_field": {
    "name": "old",
    "parent": c
  }
}

PUT my_index/_doc/a?routing=b
{
  "my_join_field": {
    "name": "old",
    "parent": b
  }
}

# 以下のようなクエリでaの親としてcを取得したい
GET my_index/_search
{
  "query": {
    "has_child": { 
      "type": "old",
      "query": {
        "match": {
          "_id": a
        }
      }
    }
  }
}

```

のようなものを想定しております。

Elasticsearchのバージョンは6.3.1です。

お手数お掛けしますが、ご教授頂ければ幸いです。  
よろしくお願い致します。

---

<div class="post-metadata">

### Author: ![tsgkdt](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/tsgkdt/32/39151_2.png) [@tsgkdt](https://discuss.elastic.co/u/tsgkdt)
#### Post date: [April 18, 2019, 1:17pm UTC](https://discuss.elastic.co/t/topic/177434/2 "2019-04-18T13:17:34Z")

</div>

既にご覧になっているかもしれませんが・・・

> **[Join field type | Elasticsearch Guide \[8.11\] | Elastic](https://www.elastic.co/guide/en/elasticsearch/reference/current/parent-join.html#_multiple_levels_of_parent_join)**

> Using multiple levels of relations to replicate a relational model is not recommended.

親を、とあるので、has\_parentなのかな？と思い、読みかえました。

> **[Has parent query | Elasticsearch Guide \[7.0\] | Elastic](https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-dsl-has-parent-query.html)**

> Note that the `has_parent` is a slow query compared to other queries in the query dsl due to the fact that it performs a join. The performance degrades as the number of matching parent documents increases. If you care about query performance you should not use this query.

と書かれており、推奨しないわ、使うとSlow Queryになるわでいいことありません。  
Discussの英語の方でも「RDBMSじゃないのだから、非正規化を検討してはどうだ」とあります。  
背景も制約も分からないので、まずは非正規化のアプローチが良いと思いますが、  
既に検討済みでしたらすみません。

---

<div class="post-metadata">

### Author: ![onorioriori](https://avatars.discourse-cdn.com/v4/letter/o/74df32/32.png) [@onorioriori](https://discuss.elastic.co/u/onorioriori)
#### Post date: [May 9, 2019, 10:06am UTC](https://discuss.elastic.co/t/topic/177434/3 "2019-05-09T10:06:10Z")

</div>

お返事遅くなり申し訳ありません。  
has\_parentクエリのドキュメントを読んだところ、

> This query returns child documents which associated parents have matched.

とありますので、マッチした親ドキュメントに紐づく子のドキュメントを取得するようです。  
今回は子のidを指定して、マッチした子ドキュメントに紐づく親のドキュメントを取得したいため、  
has\_childを使用したいと思っております。

上で記載して頂いたように、推奨されておらず、Slow Queryになってしまうようですので、  
フィールドに`parent`なるものを用意し、

```auto
PUT my_index/_doc/a
{
  "parent": "b"
}

PUT my_index/_doc/b
{
  "parent": "c"
}

```

のように保持して、ループ処理で1つ上の親を順番に取得するようにしようかと思います。

ご回答ありがとうございました 🙇‍♂️

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)
#### Post date: [June 6, 2019, 10:06am UTC](https://discuss.elastic.co/t/topic/177434/4 "2019-06-06T10:06:16Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
