Elasticaの戻り値をいい感じにラップするライブラリを書いた


PHPでElasticSearchをあつかうときの定番ライブラリにElasticaというものがある。
Symfonyで扱うときはこれをさらにラップしたFOSElasticaBundleを使うとよい。

Elasticaの難点として、クエリを投げて帰ってくる結果が連想配列で得られるのだが、これが無駄に深いネストがあったりして地味に使いづらい。

$result = $index->search($query)->getAggregations()

こんな感じで結果を取るとすると

[
    'interval' => [
        'buckets' => [
            [
                'key_as_string' => '2016-05-31T15:00:00.000Z',
                'key' => 1464706800000,
                'doc_count' => 1000,
                'editor' => [
                    'doc_count_error_upper_bound' => 0,
                    'sum_other_doc_count' => 0,
                    'buckets' => [
                        [
                            'key' => 'Emacs',
                            'doc_count' => 800,
                        ],
                        [
                            'key' => 'nano',
                            'doc_count' => 200,
                        ],
                    ],
                ],
            ],
            [
                'key_as_string' => '2016-06-30T15:00:00.000Z',
                'key' => 1467298800000,
                'doc_count' => 2000,
                'editor' => [
                    'doc_count_error_upper_bound' => 0,
                    'sum_other_doc_count' => 0,
                    'buckets' => [
                        [
                            'key' => 'SublimeText',
                            'doc_count' => 1800,
                        ],
                    ],
                ],
            ],
        ],
    ],
]

こんな感じで返ってきたりするので

$result['interval']['buckets']['editor']['buckets']['doc_count']

とかやって欲しいデータを取る。
ちょっと指が疲れて微妙なのでこの辺をいい感じにラップするライブラリElasticaFriendlyResultSetを書いた。

これを使うと

$result->interval->editor->doc_count

となる。

……あんまり変わってないじゃん!と思うかもしれないが、これをtwigから呼ぶと

{{ result['interval']['buckets']['editor']['buckets']['doc_count'] }}

{{ result.interval.editor.doc_count }}

になったり

{% for interval in result['interval']['buckets'] %}
    {% for editor in interval['editor']['buckets'] %}
        {{ editor['key'] }}: {{ editor['doc_count'] }}<br />
    {% endfor %}
{% endfor %}

{% for interval in result.interval %}
    {% for key, editor in interval.editor %}
        {{ key }}: {{ editor.doc_count }}<br />
    {% endfor %}
{% endfor %}

になったら嬉しくないですか?

ついでに今回練習を兼ねてTravis CIでの自動テスト、Coverallsでのカバレッジレポートとかいろいろ遊んだ。なんか表示がぶっ壊れてるけど。
テスト初心者だけど、カバレッジ可視化はモチベーションにつながって良いことだと思う。
passing & 100%のGitHubドヤ顔緑バッジ……もなんか出てないけど(GitHubがキャッシュするから?)。

図

ついでにPackagistにも登録したので

composer require kissge/elastica-friendly-result-set

だけでインストールできるようになった。登録は一瞬で済んだ。


Leave a Reply

Your email address will not be published. Required fields are marked *