Как я могу получить доступ к элементу массива в скрипте elasticsearch

#elasticsearch

#эластичный поиск

Вопрос:

У меня есть это отображение для моего индекса:

     "my_index": {
        "mappings": {
            "properties": {
                "medias": {
                    "properties": {
                        "media_id": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "media_type": {
                            "type": "long"
                        },
                        "variant": {
                            "properties": {
                                "height": {
                                    "type": "long"
                                },
                                "url": {
                                    "type": "text",
                                    "fields": {
                                        "keyword": {
                                            "type": "keyword",
                                            "ignore_above": 256
                                        }
                                    }
                                },
                                "width": {
                                    "type": "long"
                                }
                            }
                        },
                        "view_count": {
                            "type": "long"
                        }
                    }
                }
              
}
  

И я хочу написать сценарий для пользовательского подсчета очков, подобный этому:

     // "_source": "content",
    "query": {
        "function_score": {
            "functions": [
                {
                    "script_score": {
                        "script": {
                            "source": " (doc.medias.size() == 0 || doc.medias.view_count.size() == 0 ? 0 : doc.medias.view_count.value) "
                        }
                    
                    }
                }
            ],
            "query": {
                "match": {
                    "content": something"
                }
            },
            "score_mode": "multiply"
        }
    }
}
  

Но я получаю эту ошибку:

 "caused_by": {
                        "type": "illegal_argument_exception",
                        "reason": "No field found for [medias] in mapping with types []"
                    }
  

Я предполагаю, что я неправильно обращаюсь к view_count свойству. Как я могу это сделать? И еще одна вещь: medias поле является массивом, и если размер массива превысил 1, мне нужно получить максимум view_count s. Как я могу это сделать?

Ответ №1:

Отличное начало! Вы почти на месте, вам просто нужно получить доступ к значениям документа, подобным этому, и вы получите желаемые результаты :

     {
      "script_score": {
        "script": {
          "source": " (doc['medias.view_count'].size() == 0 ? 0 : doc['medias.view_count'].value) "
        }
      }
    }
  

Поскольку doc['medias.view_count'] на самом деле это список Java, если вам нужно получить максимальное количество просмотров, вы можете сделать это следующим образом:

     {
      "script_score": {
        "script": {
          "source": " (doc['medias.view_count'].size() == 0 ? 0 : doc['medias.view_count'].stream().max(Long::compare).get()) "
        }
      }
    }
  

Комментарии:

1. Большое вам спасибо! еще одна вещь: medias поле является массивом, и если размер массива превысил 1, мне нужно получить максимум view_counts . Как я могу это сделать?

2. И что-то еще: когда medias имеет более одного элемента, ваш скрипт view_count возвращает, какой из них?

3. doc['medias.view_count'] на самом деле это список Java, поэтому вы можете получить любой позиционный элемент в этом списке. Например, doc['medias.view_count'][2] вернул бы третий view_count