27

私は現在、FOQElasticaBundleを介して Symfony2 アプリケーションに Elasticsearch を実装しています。これまでのところ、「ストーリー」エンティティのさまざまなフィールドに適用されたブーストに基づいてうまく機能しています。構成は次のとおりです。

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:

ただし、ストーリーの「published_at」の日付に基づいてブーストを適用して、昨日公開されたストーリーが6か月前に公開されたストーリーの前に結果に表示されるようにしたいと思います-古いストーリーのスコアがわずかに優れていたとしても(明らかに、これには少し調整が必要です)。これは可能ですか?

誰かが FOQElasticaBundle を使用してこれを達成する方法を教えてくれればそれは素晴らしいことですが、それ以外の場合は、elasticsearch でこれを直接達成する方法を教えていただければ幸いです。そうすれば、私は自分で動作を試して実装し、必要に応じてバンドルします。

ありがとう。

4

3 に答える 3

47

ふぅ、多くの実験と何時間にもわたるインターウェブのトロールの後、ついに目的の動作を得ることができました! (全クレジットはクリントン・ゴームリーに贈られます。)

マッピング構成:

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クエリにもっと興味がある人のために(簡潔にするために3つの日付範囲のみ)...

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>"
            }
          }
        }
      ]
    }
  }
}'
于 2012-09-06T12:09:51.970 に答える
34

減衰スコアリング関数を使用して、時間に対するスコアリングを減らすことができます。

{
 "query": {
 "function_score": {
    "functions": [
     {
      "linear": {
        "pubdate": {
          "origin": 1398673886,
          "scale": "1h",
          "offset": 0,
          "decay": 0.1
        }
      }
    }
    ]
   }
  }
 }
于 2014-04-28T09:30:44.413 に答える
14

function_scoreに基づく完全なelasticsearch 5の例。詳細については、このブログ投稿function_score ドキュメントを参照してください。

「ハードカットオフ」のないガウス曲線で、さまざまな強度で、複数の日付範囲に基づいて、より最近のエントリをブーストできます。

{
    "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 >" }
            }
        }
    }
}
于 2017-05-04T09:49:13.240 に答える