Можно ли увеличить "новейшие" предметы с помощью elasticsearch? (FOQElasticaBundle)
В настоящее время я реализую elasticsearch в своем приложении Symfony2 через FOQElasticaBundle, и до сих пор он отлично работал на основе повышений, применяемых к различным полей моего объекта "История". Вот конфиг:
foq_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
website:
client: default
types:
story:
mappings:
title: { boost: 8 }
summary: { boost: 5 }
text: { boost: 3 }
author:
persistence:
driver: orm # orm, mongodb, propel are available
model: Acme\Bundle\StoryBundle\Entity\Story
provider:
query_builder_method: createIsActiveQueryBuilder
listener:
service: acme_story.search_index_listener
finder:
Однако я хотел бы также применить повышение, основанное на дате публикации "опубликовано", так, чтобы опубликованная вчера статья появлялась в результатах до публикации, опубликованной 6 месяцев назад, - даже если более старая история имела немного лучше оценка (очевидно, это потребует немного настройки). Возможно ли это?
Если бы кто-нибудь мог сообщить мне, как это сделать, используя FOQElasticaBundle, это было бы здорово, но в остальном я был бы признателен, если бы вы могли дать мне знать, как добиться этого непосредственно в elasticsearch, чтобы я мог попробовать и реализовать поведение самостоятельно и внести вклад в пакет, если это необходимо.
Спасибо.
Ответы
Ответ 1
Когда после много экспериментов и часов траления Interweb я, наконец, смог получить желаемое поведение! (Полный кредит - Клинтон Гормли.)
Конфигурация отображения:
mappings:
title: { boost: 8 }
summary: { boost: 5 }
text: { boost: 3 }
author:
publishedAt: { type: date }
Вот код с использованием PHP-клиента Elastica для динамического создания запроса для увеличения с использованием исходного отображения И опубликованной даты:
$query = new \Elastica_Query_Bool();
$query->addMust(new \Elastica_Query_QueryString($queryString));
$ranges = array();
for ($i = 1; $i <= 5; $i++) {
$date = new \DateTime("-$i month");
$currentRange = new \Elastica_Query_Range();
$currentRange->addField('publishedAt', array(
'boost' => (6 - $i),
'gte' => $date->getTimestamp()
));
$ranges[] = $currentRange->toArray();
}
$query->addShould($ranges);
/** @var $pagerfanta Pagerfanta */
$pagerfanta = $this->getFinder()->findPaginated($query);
И для тех из вас, кто больше интересуется сырым запросом elasticsearch (только для трех диапазонов дат для краткости)...
curl -XPOST 'http://localhost:9200/website/story/_search?pretty=true' -d '
{
"query" : {
"bool" : {
"must" : {
query_string: {
query: "<search term(s)>"
}
},
"should" : [
{
"range" : {
"publishedAt" : {
"boost" : 5,
"gte" : "<1 month ago>"
}
}
},
{
"range" : {
"publishedAt" : {
"boost" : 4,
"gte" : "<2 months ago>"
}
}
},
{
"range" : {
"publishedAt" : {
"boost" : 3,
"gte" : "<3 months ago>"
}
}
}
]
}
}
}'
Ответ 2
Вы можете использовать функцию затухания затухания, чтобы уменьшить количество очков по сравнению с временем:
{
"query": {
"function_score": {
"functions": [
{
"linear": {
"pubdate": {
"origin": 1398673886,
"scale": "1h",
"offset": 0,
"decay": 0.1
}
}
}
]
}
}
}
Ответ 3
Полный elasticsearch 5 пример, основанный на function_score. Для получения дополнительной информации см. этот blogpost и function_score docs.
Позволяет активировать более поздние записи на основе нескольких диапазонов дат с различными сильными сторонами без "жестких отключений".
{
"query": {
"function_score": {
"score_mode": "sum", // All functions outputs get summed
"boost_mode": "multiply", // The documents relevance is multiplied with the sum
"functions": [
{
// The relevancy of old posts is multiplied by at least one.
// Remove if you want to exclude old posts
"weight": 1
},
{
// Published this month get a big boost
"weight": 5,
"gauss": {
"date": { // <- Change to your date field name
"origin": "2017-04-07", // Change to current date
"scale": "31d",
"decay": 0.5
}
}
},
{
// Published this year get a boost
"weight": 2,
"gauss": {
"date": { // <- Change to your date field name
"origin": "2017-04-07", // Change to current date
"scale": "356d",
"decay": 0.5
}
}
}
],
"query": {
// The rest of your search here, change to something relevant
"match": { "title": "< your search string >" }
}
}
}
}