少し前に検証したものだが、改めて整理。
テーブルAとテーブルBを結合した結果を取得したい場合に、普通にSpring DataのRepositoryを作って@Query
のメソッドを定義してもうまくいかない。
例えば以下のようなクエリは表現できない。
select a.id, b.id, b.name from a join b on b.id = a.b_id;
これを何とかRepositoryで表現するための方法について。
少し前に検証したものだが、改めて整理。
テーブルAとテーブルBを結合した結果を取得したい場合に、普通にSpring DataのRepositoryを作って@Query
のメソッドを定義してもうまくいかない。
例えば以下のようなクエリは表現できない。
select a.id, b.id, b.name from a join b on b.id = a.b_id;
これを何とかRepositoryで表現するための方法について。
Boucing Resultsという問題がある。検索結果に重複・欠落が起きる問題。
ソートのキーに使われる項目の値が同じdocumentがあると、検索結果の順序が一定にならない可能性がある。
Elasticsearchのクエリでページネーションを行う場合、各ページへのリクエストは独立しているので、それぞれのアクセスで別のシャードにアクセスする可能性がある。
といった条件が揃うと、1ページ目で返された検索結果が次のページでも返ってくる、という事象が起きる。
これは、Elasticsearch: The Definitive Guide でも説明されている Bouncing Results という問題とのこと。
この問題と思われる事象に遭遇したため、事象の再現と対策の検証を行なった。
th:fragment
によって部品を作るのは比較的簡単にできるが、
類似の部品が出てきた時に、その中の一部を変更したい場合にどうするか?
例えば以下のようなイメージ。
barタグとbazタグだけが差分であり、その他は同じ構成になっている。
<foo id="foo1">
<div></div>
<bar></bar>
</foo>
<foo id="foo2">
<div></div>
<baz></baz>
</foo>
それぞれのfooタグを部品として定義するのも良いが、それでは重複コードが多すぎる。
GradleプラグインのTaskにInputとOutputを設定して、いずれかが変化した時にだけタスクが再実行されるようにしたいとき。
実装は簡単でも、テストはどうするか。
up-to-dateがきちんと判定できないと、変更が入った時に処理が実行されないなど致命的な不具合になる。
※Gradleのバージョンが古い(2.x)ので、最新では少し話が違うかもしれない。
Spockでテストを書くとき、setup:
, when:
, then:
という流れで書けば良いが
複数の処理を実行し、最後の結果だけでなく途中の経過も含めてassertする場合にどうすればいいか。
単純に when:
と then:
を繰り返して書けばいい。
and:
などが一見それっぽいもののようにも思えてしまうが、and:
はこの用途ではないので注意。
def ...() {
setup:
// 初期設定
when:
// 最初の処理
then:
// 最初の処理の結果をassert
when:
// 2つ目の処理
then:
// 2つ目の処理の結果をassert
}
Spring Data ElasticsearchのElasticsearchTemplateなどを使って
最終的に実行されたクエリを確認するには以下を application.yml に設定すれば良い。
spring:
data:
elasticsearch:
properties:
index:
search:
slowlog:
threshold:
query:
info: "0s"
忘れがちなのでメモ。
Spring Data ElasticsearchのローカルのノードにHTTPでアクセスするには、application.yml に以下を追加すればいい。
spring:
data:
elasticsearch:
properties:
http:
enabled: true
http://localhost:9200/
でアクセスできる。