如何使用 elasticsearch 在 Catalyst 应用程序中分页?
How to paginate in a Catalyst app using elasticsearch?
我正在使用 Web 框架 Catalyst,我想使用插件 Data::Paginator 对 elasticsearch 查询的结果进行分页。这是我现在的代码:
Root.pm
sub search :Global {
my ( $self, $c ) = @_;
my $search = $c->model('Search');
my $m = $c->req->params->{m};
my $from = 0;
my $size = 10;
my $results = $search->search(
index => 'index1',
type => 'type1',
body => {
query => {
prefix => { entree => $m }
},
from => $from,
size => $size
}
);
my $pager = Data::Paginator->new(
current_page => 1,
entries_per_page => 10,
total_entries => $results->{hits}{total},
);
my $p = { next_page=>$pager->next_page, previous_page=>$pager->previous_page };
my @res=();
for my $i ( @{ $results->{hits}->{hits} } ) {
my $h = { entree => $i->{_source}->{entree}, contenu => $i->{_source}->{contenu} };
push @res, $h;
}
$c->stash(template => 'search.tt', total => $results->{hits}{total}, m=>$m , res=>\@res, pager=>$p);
$c->forward('View::HTML');
}
还有模板
search.tt
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Résultats</title>
</head>
<body>
<h1>[% total %] résultat(s) pour [% m %]</h1>
[% IF total >0 %]
[% FOREACH h IN res %]
<h2>[% h.entree %]</h2>
<p>[% h.contenu %]</p>
[% END %]
[% ELSE %]
<p>Pas de résultat</p>
[% END %]
</body>
<footer>
<a href="/">Nouvelle recherche</a>
<a href="/search?offset=[% pager.previous_page %]&m=[% m %]">Previous Page</a>
<a href="/search?offset=[% pager.next_page %]&m=[% m %]">Next Page</a>
<a> DATA PAGINATOR TEST [% pager %]</a>
</footer>
</html>
我想在点击 "Next Page" 或 "Previous Page" 时通过 elasticsearch 进行新查询并显示新结果:
my $results = $search->search(
index => 'index1',
type => 'type1',
body => {
query => {
prefix => { entree => $m }
},
from => $from + 10,
OR from => $from -10,
size => $size
}
);
关于如何做到这一点的一些提示会很好,谢谢。
编辑 1:
Root_v2.pm
sub search :Global {
my ( $self, $c ) = @_;
my $search = $c->model('Search');
my $m = $c->req->params->{m};
my $offset = $c->req->params->{offset} ? $c->req->params->{offset} : 0;
my $from = 0;
my $size = 10;
my $results = $search->search(
index => 'index1',
type => 'type1',
body => {
query => {
prefix => { entree => $m }
},
from => $offset*$size,
size => $size
}
);
my $pager = Data::Paginator->new(
current_page => $offset,
entries_per_page => 10,
total_entries => $results->{hits}{total},
);
my $p = { next_page=>$pager->next_page, previous_page=>$pager->previous_page };
my @res=();
for my $i ( @{ $results->{hits}->{hits} } ) {
my $h = { entree => $i->{_source}->{entree}, contenu => $i->{_source}->{contenu} };
push @res, $h;
}
$c->stash(template => 'search.tt', total => $results->{hits}{total}, m=>$m , res=>\@res, pager=>$p);
$c->forward('View::HTML');
}
我从 search.tt 文件中的 href 获取偏移量,并用它来修改 elasticsearch 查询中的 "from" 参数。
但是我对来自 Data::Paginator 的 "current_page" 有一个问题:它永远不会等于 0,即使我的 $offset 本身等于 0(参见 current_page => $offset ).当我第一次点击下一页时,我错过了第 10 到第 20 个结果。
行为是这样的:
Click on search button: OFFSET=0 / CURRENT_PAGE=1 / NEXT_PAGE=2
/ PREVIOUS_PAGE=not def
Click on next page button: OFFSET=2 / CURRENT_PAGE=2 / NEXT_PAGE=3
/ PREVIOUS_PAGE=1
Click on previous page button: OFFSET=1 / CURRENT_PAGE=1 / NEXT_PAGE=2
/ PREVIOUS_PAGE=not def
你可以看到当我第一次点击下一页按钮时我错过了结果,因为我的偏移量直接从 0 到 2 跳过 1。
编辑 2
Root_v3.pm
修改:
my $offset = $c->req->params->{offset} ? $c->req->params->{offset} : O;
▼▼▼
my $offset = $c->req->params->{offset} ? $c->req->params->{offset} : 1;
和
from => $offset*$size,
▼▼▼
from => ($offset-1)*$size,
现在可以使用了!
查看原始 post 以及我所做的两次编辑。
我正在使用 Web 框架 Catalyst,我想使用插件 Data::Paginator 对 elasticsearch 查询的结果进行分页。这是我现在的代码:
Root.pm
sub search :Global {
my ( $self, $c ) = @_;
my $search = $c->model('Search');
my $m = $c->req->params->{m};
my $from = 0;
my $size = 10;
my $results = $search->search(
index => 'index1',
type => 'type1',
body => {
query => {
prefix => { entree => $m }
},
from => $from,
size => $size
}
);
my $pager = Data::Paginator->new(
current_page => 1,
entries_per_page => 10,
total_entries => $results->{hits}{total},
);
my $p = { next_page=>$pager->next_page, previous_page=>$pager->previous_page };
my @res=();
for my $i ( @{ $results->{hits}->{hits} } ) {
my $h = { entree => $i->{_source}->{entree}, contenu => $i->{_source}->{contenu} };
push @res, $h;
}
$c->stash(template => 'search.tt', total => $results->{hits}{total}, m=>$m , res=>\@res, pager=>$p);
$c->forward('View::HTML');
}
还有模板
search.tt
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Résultats</title>
</head>
<body>
<h1>[% total %] résultat(s) pour [% m %]</h1>
[% IF total >0 %]
[% FOREACH h IN res %]
<h2>[% h.entree %]</h2>
<p>[% h.contenu %]</p>
[% END %]
[% ELSE %]
<p>Pas de résultat</p>
[% END %]
</body>
<footer>
<a href="/">Nouvelle recherche</a>
<a href="/search?offset=[% pager.previous_page %]&m=[% m %]">Previous Page</a>
<a href="/search?offset=[% pager.next_page %]&m=[% m %]">Next Page</a>
<a> DATA PAGINATOR TEST [% pager %]</a>
</footer>
</html>
我想在点击 "Next Page" 或 "Previous Page" 时通过 elasticsearch 进行新查询并显示新结果:
my $results = $search->search(
index => 'index1',
type => 'type1',
body => {
query => {
prefix => { entree => $m }
},
from => $from + 10,
OR from => $from -10,
size => $size
}
);
关于如何做到这一点的一些提示会很好,谢谢。
编辑 1:
Root_v2.pm
sub search :Global {
my ( $self, $c ) = @_;
my $search = $c->model('Search');
my $m = $c->req->params->{m};
my $offset = $c->req->params->{offset} ? $c->req->params->{offset} : 0;
my $from = 0;
my $size = 10;
my $results = $search->search(
index => 'index1',
type => 'type1',
body => {
query => {
prefix => { entree => $m }
},
from => $offset*$size,
size => $size
}
);
my $pager = Data::Paginator->new(
current_page => $offset,
entries_per_page => 10,
total_entries => $results->{hits}{total},
);
my $p = { next_page=>$pager->next_page, previous_page=>$pager->previous_page };
my @res=();
for my $i ( @{ $results->{hits}->{hits} } ) {
my $h = { entree => $i->{_source}->{entree}, contenu => $i->{_source}->{contenu} };
push @res, $h;
}
$c->stash(template => 'search.tt', total => $results->{hits}{total}, m=>$m , res=>\@res, pager=>$p);
$c->forward('View::HTML');
}
我从 search.tt 文件中的 href 获取偏移量,并用它来修改 elasticsearch 查询中的 "from" 参数。
但是我对来自 Data::Paginator 的 "current_page" 有一个问题:它永远不会等于 0,即使我的 $offset 本身等于 0(参见 current_page => $offset ).当我第一次点击下一页时,我错过了第 10 到第 20 个结果。
行为是这样的:
Click on search button: OFFSET=0 / CURRENT_PAGE=1 / NEXT_PAGE=2 / PREVIOUS_PAGE=not def
Click on next page button: OFFSET=2 / CURRENT_PAGE=2 / NEXT_PAGE=3 / PREVIOUS_PAGE=1
Click on previous page button: OFFSET=1 / CURRENT_PAGE=1 / NEXT_PAGE=2 / PREVIOUS_PAGE=not def
你可以看到当我第一次点击下一页按钮时我错过了结果,因为我的偏移量直接从 0 到 2 跳过 1。
编辑 2
Root_v3.pm
修改:
my $offset = $c->req->params->{offset} ? $c->req->params->{offset} : O;
▼▼▼
my $offset = $c->req->params->{offset} ? $c->req->params->{offset} : 1;
和
from => $offset*$size,
▼▼▼
from => ($offset-1)*$size,
现在可以使用了!
查看原始 post 以及我所做的两次编辑。