Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm currently implementing elasticsearch in my Symfony2 application via the FOQElasticaBundle and so far it's been working great based on boosts applied to various fields of my "Story" entity. Here is the config:

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: AcmeBundleStoryBundleEntityStory
                        provider:
                            query_builder_method: createIsActiveQueryBuilder
                        listener:
                            service: acme_story.search_index_listener
                        finder:

However I'd like to also apply a boost based on the "published_at" date of the story, so that a story published yesterday would appear in the results before a story published 6 months ago - even if the older story had a slightly better score (obviously this will need a bit of tweaking). Is this possible?

If anyone could let me know how to achieve this using FOQElasticaBundle that would be great, but otherwise I'd appreciate it if you could let me know how to achieve this directly in elasticsearch so I can try and implement the behaviour myself and contribute to the bundle if needs be.

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
259 views
Welcome To Ask or Share your Answers For Others

1 Answer

Whew, after much experimentation and hours of trawling the Interweb I finally managed to get the desired behavior! (Full credit goes to Clinton Gormley.)

Mapping configuration:

mappings:
    title: { boost: 8 }
    summary: { boost: 5 }
    text: { boost: 3 }
    author:
    publishedAt: { type: date }

Here is the code using the PHP client, Elastica, to dynamically build the query to boost using the original mapping AND the published date:

$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);

And for those of you more interested in the raw elasticsearch query (only with 3 date ranges for brevity)...

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>"
            }
          }
        }
      ]
    }
  }
}'

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...