以下内容对我来说非常有用。确保您使用的是常规格式的 sort 定义列表,如下所示:
function getSortDefinitions() {
return [
'newest' => [
[ 'created_at' => 'desc' ],
[ 'id' => 'desc' ],
],
'oldest' => [
[ 'created_at' => 'asc' ],
[ 'id' => 'asc' ],
]
'highest' => [
[ 'price' => 'desc' ],
[ 'created_at' => 'desc' ],
[ 'id' => 'desc' ],
],
'lowest' => [
[ 'price' => 'asc' ],
[ 'created_at' => 'asc' ],
[ 'id' => 'asc' ],
],
];
}
旁白:添加id 使结果集对具有相同时间戳的记录具有可预测的顺序。这种情况经常发生在同时保存所有记录的测试装置中。
现在,每当有人搜索时,他们通常会选择几个过滤器,可能是一个查询,肯定是一个排序顺序。创建一个存储它的表,以便您可以生成要使用的搜索上下文:
create table search_contexts (
id int primary,
hash varchar(255) not null,
query varchar(255) not null,
filters json not null,
sort varchar(255) not null,
unique search_contexts_hash_uk (hash)
);
在您选择的语言中使用类似以下的内容来插入并获取对搜索上下文的引用:
function saveSearchContext($query, $filters, $sort)
{
// Assuming some magic re: JSON encoding of $filters
$hash = md5(json_encode(compact('query', 'filters', 'sort')));
return SearchContext::firstOrCreate(compact('hash', 'query', 'filters', 'sort'));
}
请注意,如果没有具有相同参数的搜索上下文,我们只会插入搜索上下文。因此,每次搜索我们都会得到一个唯一的行。您可以选择被音量淹没并在每次搜索时保存一个。如果您选择这样做,请使用 uniqid 而不是 md5 并创建记录。
在结果索引页面上,每当您生成指向详细页面的链接时,请使用哈希作为查询参数,如下所示:
http://example.com/details/2456?search=7ddf32e17a6ac5ce04a8ecbf782ca509
在您的详细信息页面代码中,执行以下操作:
function getAdjacentDocument($search, $documentId, $next = true) {
$sortDefinitions = getSortDefinitions();
if (!$next) {
// Reverse the sort definitions by looping through $sortDefinitions
// and swapping asc and desc around
$sortDefinitions = array_map($sortDefinitions, function ($defn) {
return array_map($defn, function ($array) {
$field = head(array_keys($array));
$direction = $array[$field];
$direction = $direction == 'asc' ? 'desc' : 'asc';
return [ $field => $direction ];
});
});
}
// Add a must_not filter which will ensure that the
// current page's document ID is *not* in the results.
$filters['blacklist'] = $documentId;
$params = [
'body' => [
'query' => generateQuery($search->query, $filters),
'sort' => $sortDefinitions[$sort],
// We are only interested in 1 document adjacent
// to this one, limit results
'size' => 1
]
];
$response = Elasticsearch::search($params);
if ($response['found']) {
return $response['hits']['hits'][0];
}
}
function getNextDocument($search, $documentId) {
return getAdjacentDocument($search, $documentId, true);
}
function getPreviousDocument($search, $documentId) {
return getAdjacentDocument($search, $documentId, false);
}
// Retrieve the search context given it's hash as query parameter
$searchContext = SearchContext::whereHash(Input::query('search'))->first();
// From the route segment
$documentId = Input::route('id');
$currentDocument = Elasticsearch::get([
'id' => $documentId,
'index' => 'documents'
]);
$previousDocument = getPreviousDocument($searchContext, $documentId);
$nextDocument = getNextDocument($searchContext, $documentId);
这种技术的关键是除了生成两个搜索
get 用于详细记录。
一个搜索从该记录向前,另一个从该记录向后搜索,
在这两种情况下给定相同的搜索上下文,因此它们可以相互配合。
在这两种情况下,您都会获取第一条不是我们当前记录的记录,它应该
是正确的。