Как я могу выполнить прокрутку поиска в MetaCPAN?

Я пытаюсь преобразовать этот скрипт, чтобы использовать новый официальный клиент Elasticsearch вместо старого (ныне устаревшего) ElasticSearch.pm, но я не могу заставить прокручиваемый поиск работать. Вот что у меня есть:

#! /usr/bin/perl

use strict;
use warnings;
use 5.010;

use Elasticsearch ();
use Elasticsearch::Scroll ();

my $es = Elasticsearch->new(
  nodes => 'http://api.metacpan.org:80',
  cxn   => 'NetCurl',
  cxn_pool => 'Static::NoPing',
  #log_to   => 'Stderr',
  #trace_to => 'Stderr',
);

say 'Getting all results at once works:';
my $results = $es->search(
  index => 'v0',
  type  => 'release',
  body  => {
    filter => { range => { date => { gte => '2013-11-28T00:00:00.000Z' } } },
    fields => [qw(author archive date)],
  },
);

foreach my $hit (@{ $results->{hits}{hits} }) {
  my $field = $hit->{fields};
  say "@$field{qw(date author archive)}";
}

say "\nUsing a scrolled search does not work:";
my $scroller = Elasticsearch::Scroll->new(
  es          => $es,
  index       => 'v0',
  search_type => 'scan',
  size        => 100,
  type        => 'release',
  body => {
    filter => { range => { date => { gte => '2013-11-28T00:00:00.000Z' } } },
    fields => [qw(author archive date)],
  },
);

while (my $hit = $scroller->next) {
  my $field = $hit->{fields};
  say "@$field{qw(date author archive)}";
} # end while $hit

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

Using a scrolled search does not work:
[Request] ** [http://api.metacpan.org:80]-[500]
ActionRequestValidationException[Validation Failed: 1: scrollId is missing;],
called from sub Elasticsearch::Transport::try {...}
at .../Try/Tiny.pm line 83. With vars: {'body' =>
'ActionRequestValidationException[Validation Failed: 1: scrollId is missing;]',
'request' => {'path' => '/_search/scroll','serialize' => 'std',
'body' => 'c2Nhbjs1OzE3MjU0NjM2MjowakFELUU3VFFibTJIZW1ibUo0SUdROzE3MjU0NjM2NDowakFELUU3VFFibTJIZW1ibUo0SUdROzE3MjU0NjM2MTowakFELUU3VFFibTJIZW1ibUo0SUdROzE3MjU0NjM2MDowakFELUU3VFFibTJIZW1ibUo0SUdROzE3MjU0NjM2MzowakFELUU3VFFibTJIZW1ibUo0SUdROzE7dG90YWxfaGl0czoxNDQ7',
'method' => 'GET','qs' => {'scroll' => '1m'},'ignore' => [],
'mime_type' => 'application/json'},'status_code' => 500}

Что я делаю неправильно? Я использую Elasticsearch 0.75 и Elasticsearch-Cxn-NetCurl 0.02 и Perl 5.18.1.

2 ответа

Решение

Я наконец-то начал работать с новым официальным клиентом Search::Elasticsearch. Вот короткая версия:

#! /usr/bin/perl

use strict;
use warnings;
use 5.010;

use Search::Elasticsearch ();

my $es = Search::Elasticsearch->new(
  cxn_pool => 'Static::NoPing',
  nodes    => 'api.metacpan.org:80',
);

my $scroller = $es->scroll_helper(
  index       => 'v0',
  type        => 'release',
  search_type => 'scan',
  scroll      => '2m',
  size        => 100,
  body        => {
    fields => [qw(author archive date)],
    query  => { range => { date => { gte => '2015-02-01T00:00:00.000Z' } } },
  },
);

while (my $hit = $scroller->next) {
  my $field = $hit->{fields};
  say "@$field{qw(date author archive)}";
} # end while $hit

Обратите внимание, что записи не сортируются при прокрутке поиска. Я свалил записи во временную базу данных и отсортировал их локально. Обновленный скрипт находится на GitHub.

У меня нет прямого ответа, но у меня может быть подход к решению проблем:

Я перешел по вашей ссылке на Elasticsearch::Client и нашел метод scroll():

https://metacpan.org/pod/Elasticsearch::Client::Direct

Этот метод требует scroll а также scroll_id в качестве параметров. scroll это количество минут, которое вы можете продолжать вызывать метод прокрутки до истечения срока поиска. scroll_id является маркером места, где закончился последний вызов scroll().

$results = $e->scroll(
    scroll      => '1m',
    scroll_id   => $id
);

Elasticsearch::Scroll объектно-ориентированная оболочка вокруг scroll(), которая скрывает scroll а также scroll_id,

Я бы побежал perl -d на вашем сценарии, и перейдите к $scroller->next и следуйте за ним как можно дальше вниз по кроличьей норе. Что-то там пытается найти, который должен быть заполнен scroll_id или же scrollId и терпит неудачу.

Мое описание здесь, по общему признанию, довольно грубое... Я наткнулся на точное описание того, что такое идентификатор прокрутки и что он делает во время поиска в Google, но я не могу найти его снова.

Другие вопросы по тегам