# Изменение родителей в индексе

**URL:** <https://discuss.elastic.co/t/topic/208941>\
**Category:** Вопросы на русском языке\
**Created:** [November 21, 2019, 4:59pm UTC](https://discuss.elastic.co/t/topic/208941 "2019-11-21T16:59:31Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ekaterina\_Nekrasova](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ekaterina_nekrasova/32/46505_2.png) [@Ekaterina\_Nekrasova](https://discuss.elastic.co/u/Ekaterina_Nekrasova)\
**Post date:** [November 21, 2019, 4:59pm UTC](https://discuss.elastic.co/t/topic/208941/1 "2019-11-21T16:59:31Z")

</div>

Привет !

я хочу сделать индекс в котором будет два типа Group и Person. Group - Parent, Person - child. в каждую группу может входить несколько людей. проблема в томь что состав групп может менияться, так что мне нужно так же менять родителей у детей. возможно ли менять каким либо образом routing и ка это делать?

Спасибо

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [November 21, 2019, 5:30pm UTC](https://discuss.elastic.co/t/topic/208941/2 "2019-11-21T17:30:05Z")

</div>

Надо удалить старую запись используя старый раутинг, и потом добавить измененную запись используя новый.

---

<div class="post-metadata">

**Author:** ![Ekaterina\_Nekrasova](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ekaterina_nekrasova/32/46505_2.png) [@Ekaterina\_Nekrasova](https://discuss.elastic.co/u/Ekaterina_Nekrasova)\
**Post date:** [November 21, 2019, 5:39pm UTC](https://discuss.elastic.co/t/topic/208941/3 "2019-11-21T17:39:09Z")

</div>

спасибо! т.е. если у меня 20 000 000 человек, то мне нужно будет всех их переписывать....  
А если попробовать сделать группу ребенком и человека - родителем? возможно ли будет отсортировать людей по дате рождения, и выбрать тех, кто находится в первых 10 разных группах ?

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [November 21, 2019, 5:54pm UTC](https://discuss.elastic.co/t/topic/208941/4 "2019-11-21T17:54:50Z")

</div>

> [@Ekaterina\_Nekrasova](#):
>
> т.е. если у меня 20 000 000 человек, то мне нужно будет всех их переписывать....

Тут либо переписывать родителя или всех детей. В elasticsearch любое изменение записи это ее удаление и запись снова. Просто если раутинг не меняется то elasticsearch это делает автоматически.

> [@Ekaterina\_Nekrasova](#):
>
> А если попробовать сделать группу ребенком и человека - родителем?

У записи не может быть больше одного родителя.

---

<div class="post-metadata">

**Author:** ![Ekaterina\_Nekrasova](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ekaterina_nekrasova/32/46505_2.png) [@Ekaterina\_Nekrasova](https://discuss.elastic.co/u/Ekaterina_Nekrasova)\
**Post date:** [November 21, 2019, 5:58pm UTC](https://discuss.elastic.co/t/topic/208941/5 "2019-11-21T17:58:21Z")

</div>

я думаю дулировать детей. и поэтому будет дублироваться информация. вот и возник вопрос о distinct query c aggregation

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [November 21, 2019, 6:05pm UTC](https://discuss.elastic.co/t/topic/208941/6 "2019-11-21T18:05:32Z")

</div>

> [@Ekaterina\_Nekrasova](#):
>
> я думаю дулировать детей.

Тогда я не понимаю, что вы пытаетесь тут сделать.

---

<div class="post-metadata">

**Author:** ![Ekaterina\_Nekrasova](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ekaterina_nekrasova/32/46505_2.png) [@Ekaterina\_Nekrasova](https://discuss.elastic.co/u/Ekaterina_Nekrasova)\
**Post date:** [November 21, 2019, 6:09pm UTC](https://discuss.elastic.co/t/topic/208941/7 "2019-11-21T18:09:16Z")

</div>

я сдделаю структуру Person - parent, Group-child.  
таким образом для каждого родителся будет только один ребенок.  
мне нужно отсоритровать людей и выбрать только из первых 10 разных групп  
|person|group|  
|1|1|  
|2|2|  
|3|2|  
|4|3|  
|5|4|  
|6|5|  
|7|6|  
|8|7|  
|9|7|  
|10|8|  
|11|9|  
|12|10|  
|13|11|

т.е. я должна полечть только людей с 1 по 12

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [November 21, 2019, 6:10pm UTC](https://discuss.elastic.co/t/topic/208941/8 "2019-11-21T18:10:09Z")

</div>

А зачем тогда создавать 2 записи?

---

<div class="post-metadata">

**Author:** ![Ekaterina\_Nekrasova](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ekaterina_nekrasova/32/46505_2.png) [@Ekaterina\_Nekrasova](https://discuss.elastic.co/u/Ekaterina_Nekrasova)\
**Post date:** [November 21, 2019, 6:12pm UTC](https://discuss.elastic.co/t/topic/208941/9 "2019-11-21T18:12:12Z")

</div>

потому что группы будут меняться каждый день

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [November 21, 2019, 7:09pm UTC](https://discuss.elastic.co/t/topic/208941/10 "2019-11-21T19:09:22Z")

</div>

А если человек 9 в 1-й группе то как список должен быть отсортирован? Тот же вопрос про человека под номером 14.

---

<div class="post-metadata">

**Author:** ![Ekaterina\_Nekrasova](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ekaterina_nekrasova/32/46505_2.png) [@Ekaterina\_Nekrasova](https://discuss.elastic.co/u/Ekaterina_Nekrasova)\
**Post date:** [November 22, 2019, 10:30am UTC](https://discuss.elastic.co/t/topic/208941/11 "2019-11-22T10:30:17Z")

</div>

> [@Ekaterina\_Nekrasova](#):
>
> |person|group|  
> |1|1|  
> |2|2|  
> |3|2|  
> |4|10|  
> |5|4|  
> |6|5|  
> |7|6|  
> |8|7|  
> |9|1|  
> |10|8|  
> |11|9|  
> |12|1|  
> |13|11|  
> |14|3|  
> |15|11|

у нас уже был вечер.... нужно напечатать группы. для примера выше это должно быть `1 2 10 4 5 6 7 8 9 11 `  
т.е. отсортировать родителей и потом выбрать первых 10 distinct детей

---

<div class="post-metadata">

**Author:** ![Ekaterina\_Nekrasova](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ekaterina_nekrasova/32/46505_2.png) [@Ekaterina\_Nekrasova](https://discuss.elastic.co/u/Ekaterina_Nekrasova)\
**Post date:** [November 22, 2019, 2:46pm UTC](https://discuss.elastic.co/t/topic/208941/12 "2019-11-22T14:46:19Z")

</div>

```
{
  "from": 0,
  "query": {
    "has_parent": {
      "parent_type": "persontype",
      "score": true,
      "query": {
        "bool": {
          "must": [
            {
              "bool": {
                "must": [
                  {
                    "query_string": {
                      "fields": [
                        "name"
                      ],
                      "lenient": true,
                      "query": "paulina cruz"
                    }
                  }
                ]
              }
            }
          ]
        }
      },
      "inner_hits": {
        "highlight": {
          "fields": {
            "name": {}
          }
        }
      }
    }
  },
  "aggs": {
    "unique_title": {
      "terms": {
        "field": "documentId",
        "order": {
          "max_score": "desc"
        }
      },
      "aggs": {
        "max_score": {
          "max": {
            "script": "_score"
          }
        }
      }
    }
  },
  "_source": {
    "excludes": [
      "*"
    ]
  }
}

```

вот какое примерное query у меня получилось. выдает более менее корректные результаты.  
Следующий вопрос - я изначально использовала

```
"query": {
"bool": {
  "must": [
    {
      "bool": {
        "must": [
          {
            "query_string": {
              "fields": [
                "name"
              ],
              "lenient": true,
              "query": "*paulina cruz*"
            }
          }
        ]
      }
    }
  ]
}
  }

```

и если я используб точно такое же query в HasParent я получаю другие результаты.  
фильтр только по родителям дает мне 11 результатов, но когда я фильтрую родителей через детей я получаю 8 результатов в другом порядке.

Вопрос - почему одно и тоже query дает разные результаты и как этого избежать?

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [November 24, 2019, 10:04pm UTC](https://discuss.elastic.co/t/topic/208941/13 "2019-11-24T22:04:13Z")

</div>

Так это два очень разных запроса, один ищет по суффиксу и префиксу а второй по обычному совпадению.

---

<div class="post-metadata">

**Author:** ![Ekaterina\_Nekrasova](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ekaterina_nekrasova/32/46505_2.png) [@Ekaterina\_Nekrasova](https://discuss.elastic.co/u/Ekaterina_Nekrasova)\
**Post date:** [November 25, 2019, 9:51am UTC](https://discuss.elastic.co/t/topic/208941/14 "2019-11-25T09:51:00Z")

</div>

я использовала именно запрос query string в двух случаях. и он мне выдает разные результаты

```
"query": {
"bool": {
  "must": [
    {
      "bool": {
        "must": [
          {
            "query_string": {
              "fields": [
                "name"
              ],
              "lenient": true,
              "query": "*paulina cruz*"
            }
          }
        ]
      }
    }
  ]
}
  }

```

при запросе конкретно к PersonType 11 записей

```
15 Paulina Name Cruz
17 Name Paulina Cruz
19 Cruz
22 Cruz Name NAme
21 NAme Cruz
20 Name Paulina
13 Paulina Crruz
16 Paulina-Name Cruz
18 Paulina
23 Paulina Name Name

```

при запросе hasParent 8 записей

```
17 Name Paulina Cruz
19 Cruz
22 Cruz Name NAme
21 NAme Cruz
20 Name Paulina
16 Paulina-Name Cruz
18 Paulina
23 Paulina Name Name

```

score для первых записей 2 для остальных всегда 1. может у вас есть предложения как сделыть поиск более релевантным ?

---

<div class="post-metadata">

**Author:** ![Ekaterina\_Nekrasova](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ekaterina_nekrasova/32/46505_2.png) [@Ekaterina\_Nekrasova](https://discuss.elastic.co/u/Ekaterina_Nekrasova)\
**Post date:** [November 25, 2019, 10:02am UTC](https://discuss.elastic.co/t/topic/208941/15 "2019-11-25T10:02:11Z")

</div>

извините ! я поняла почему у меня выдаются неправильные результаты....

 ![image](https://us1.discourse-cdn.com/elastic/original/3X/d/e/de47ec78b6e52f7a662517d81a42863aa39f48f5.png)

---

<div class="post-metadata">

**Author:** ![Ekaterina\_Nekrasova](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ekaterina_nekrasova/32/46505_2.png) [@Ekaterina\_Nekrasova](https://discuss.elastic.co/u/Ekaterina_Nekrasova)\
**Post date:** [November 25, 2019, 11:33am UTC](https://discuss.elastic.co/t/topic/208941/16 "2019-11-25T11:33:09Z")

</div>

новый вопрос 😀

возможно ли сортировать детей по нескольким полям у родителей ? т.е я хочу сортирвать сначала по score и потом по дате рождения.

```
{
  "from": 0,
  "query": {
"has_parent": {
  "parent_type": "persontype",
  "score": true,
  "query": {
    "function_score": {
      "query": {
        "common": {
          "name": {
            "query": "paulina cruz",
            "cutoff_frequency": 0.001,
            "low_freq_operator": "and"
          }
        }
      },
      "script_score": {
        "script": "_score * doc['dateOfBirth'].value"
      }
    }
  },
  "inner_hits": {
    "highlight": {
      "fields": {
        "name": {},
        "dateOfBirth": {}
      }
    }
  }
}
  },
  "aggs": {
"unique_title": {
  "terms": {
    "field": "documentId",
    
    "order": {
      "avg_score": "desc"
    },
    "size": 5
  },
  "aggs": {
    "avg_score": {
      "max": {
        "script": "_score"
      }
    },
    "bucket_count": {
      "cardinality": {
        "field": "documentId"
      }
    }
  }
},
"distinct_terms": {
  "cardinality": {
    "field": "documentId"
  }
}
  },
  "_source": {
"excludes": [
  "*"
]
  }
}

```

если можно использовать только script\_score, то по двум полям сортировать не получится ?

второй вопрос - как можно сделать pagination с агрегациями ?

```
  "aggs": {
    "unique_title": {
      "terms": {
        "field": "documentId",
        "include": {
          "partition": 1,
          "num_partitions": 3
        },
        "order": {
          "avg_score": "desc"
        },
        "size": 5
      },
      "aggs": {
        "avg_score": {
          "max": {
            "script": "_score"
          }
        },
        "bucket_count": {
          "cardinality": {
            "field": "documentId"
          }
        }
      }
    },
    "distinct_terms": {
      "cardinality": {
        "field": "documentId"
      }
    }
  },

```

я пробовала с includes, но как я могу рассчитать num\_partition ?

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [November 26, 2019, 7:40pm UTC](https://discuss.elastic.co/t/topic/208941/17 "2019-11-26T19:40:00Z")

</div>

Pagination работает только с [composite](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-composite-aggregation.html) aggs.

---

<div class="post-metadata">

**Author:** ![Ekaterina\_Nekrasova](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ekaterina_nekrasova/32/46505_2.png) [@Ekaterina\_Nekrasova](https://discuss.elastic.co/u/Ekaterina_Nekrasova)\
**Post date:** [November 27, 2019, 12:02pm UTC](https://discuss.elastic.co/t/topic/208941/18 "2019-11-27T12:02:44Z")

</div>

т.е. либо мы обновляем версию, либо берем 1000 buckets и используем кэш....

я столкнулась с проблемой: когда score одинаковый для всех записей, buckets беруться в рандомном порядке. как я могу их выбрать по их Id в том порядке в котором они появляются в query ?

 ![image](https://us1.discourse-cdn.com/elastic/original/3X/4/5/45afac971bb52a71b5199df3c052ede8ad0d57b3.png)

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [November 27, 2019, 7:31pm UTC](https://discuss.elastic.co/t/topic/208941/19 "2019-11-27T19:31:20Z")

</div>

Можно попробовать как-нибудь объединить ключи в [script](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#search-aggregations-bucket-terms-aggregation-script).

---

<div class="post-metadata">

**Author:** ![Ekaterina\_Nekrasova](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ekaterina_nekrasova/32/46505_2.png) [@Ekaterina\_Nekrasova](https://discuss.elastic.co/u/Ekaterina_Nekrasova)\
**Post date:** [November 28, 2019, 9:34am UTC](https://discuss.elastic.co/t/topic/208941/20 "2019-11-28T09:34:01Z")

</div>

Спасибо большое за все подсказки !  
в итоге у мения получилось следуьщее query

```
{
  "aggs": {
    "groupId": {
      "aggs": {
        "current_score": {
          "max": {
            "script": {
              "inline": "_score"
            }
          }
        }
      },
      "terms": {
        "field": "documentId",
        "order": [
          {
            "current_score": "desc"
          }
        ],
        "size": 10
      }
    },
    "totalDistinct": {
      "cardinality": {
        "field": "documentId"
      }
    }
  },
  "from": 0,
  "query": {
    "has_parent": {
      "query": {
        "function_score": {
          "functions": [
            {
              "script_score": {
                "script": {
                  "inline": "doc['dateOfBirth'].value",
                  "lang": "groovy"
                }
              }
            }
          ],
          "query": {
            "bool": {
              "must": [
                {
                  "bool": {
                    "minimum_should_match": 1,
                    "should": [
                      {
                        "query_string": {
                          "boost": 2,
                          "fields": [
                            "name"
                          ],
                          "lenient": true,
                          "query": "*Paulina Cruz*"
                        }
                      },
                      {
                        "query_string": {
                          "fields": [
                            "name.keyword"
                          ],
                          "lenient": true,
                          "query": "*Paulina Cruz*"
                        }
                      }
                    ]
                  }
                },
                {
                  "bool": {
                    "must": [
                      {
                        "exists": {
                          "field": "id"
                        }
                      }
                    ]
                  }
                }
              ]
            }
          }
        }
      },
      "score": true,
      "type": "persontype"
    }
  },
  "_source": {
    "excludes": [
      "*"
    ]
  }
}

```

query для нахождения общего количества элементов

```
{
  "aggs": {
    "totalDistinct": {
      "cardinality": {
        "field": "documentId"
      }
    }
  },
  "query": {
    "has_parent": {
      "query": {
        "bool": {
          "must": [
            {
              "exists": {
                "field": "id"
              }
            }
          ]
        }
      },
      "type": "persontype"
    }
  },
  "_source": {
    "excludes": [
      "*"
    ]
  }
}

```

C# версия

```
body
                    .Index(_type.GetIndexName())
                    .Source(src => src.ExcludeAll())
                    .Query(q => q.HasParent<PersonType>(
                               p => p
                                       .Score(true)
                                       .Query(qqq => qqq
                                                  .FunctionScore(fs => fs
                                                                       .Query(qq => qq.Bool(b => b
                                                                                                 .Filter(permissionContainer, personFilter)
                                                                                                 .Must(queryContainers.ToArray())))
                                                                       .Functions(fct => fct
                                                                                      .ScriptScore(ss => ss
                                                                                                       .Script(cs => cs
                                                                                                                     .Inline(_descriptors.GetOrderScript(parameters.Sort))
                                                                                                                     .Lang(ScriptLang.Groovy))
                                         ))))));

                body.Aggregations(
                    aggs => aggs
                            .Terms("groupId", gr => gr
                                    .Field(f => f.DocumentId)
                                    .Order(
                                        new TermsOrder
                                        {
                                            Key = "current_score",
                                            Order = parameters.Sort.Order == Order.ASC
                                                        ? appliedSort ? SortOrder.Ascending : SortOrder.Descending
                                                        : SortOrder.Descending
                                        })
                                    .Size(parameters.Start + parameters.Length)
                                    .Aggregations(
                                           aggss => aggss
                                               .Max("current_score", tt => tt.Script("_score"))))
                            .Cardinality("totalDistinct", c => c.Field(f => f.DocumentId))
                );

                body.From(0);

                return body;

```

т.к. используем вегсию 5,5 многие aggregations для нас недоступны. поэтому для pagination я брала все элементы (`parameters.Start + parameters.Length`) и потом из них выбирала последние.

```
var response = Query(parameters, user, applyPermissions, flags);
            return new SearchResult<long>
            {
                Items = (response.Aggregations["groupId"] as BucketAggregate)?
                    .Items
                        .Cast<KeyedBucket<object>>()
                        .Select(bucket => long.Parse(bucket.KeyAsString ?? bucket.Key.ToString()))
                        .Skip(parameters.Start)
                        .ToList(),
                ItemsCount = (long?)((ValueAggregate)response.Aggregations["totalDistinct"])?.Value ?? 0,
                TotalCount = CountByType(user, applyPermissions, flags)
            };

```

Надеюсь мой опыт кому-нибудь поможет !  
Еще раз, большое спасибо

[Next page](https://discuss.elastic.co/t/topic/208941.md?page=2)
