Closed3

elasticsearchに対するドキュメントの保存は非同期?

bookstorebookstore

ドキュメントを保存した直後、検索をしてみたがドキュメントを取得できなかった。

class ElasticsearchFistStepTest {

    @Test
    fun firstStep() {
        val esClient = run {
            val lowRestClient = RestClient.builder(HttpHost("localhost", 9200)).build()
            val transport = RestClientTransport(lowRestClient, JacksonJsonpMapper())
            ElasticsearchClient(transport)
        }

        // インデックスを作成する
        esClient.indices().create { c -> c.index("demo-index") }

        // ドキュメントを作成する
        // id を指定していないため、elasticsearchにより採番される
        val resp1 = esClient.index<Item> { c ->
            c.index("demo-index").document(Item("name-1", "category-1", 100))
        }

        // ドキュメントを検索する
        // ここで何も返ってこない
        esClient.search(
            { _0 ->
                _0.index("demo-index").query { _1 ->
                    _1.matchAll { _2 -> _2 }
                }
            },
            Item::class.java
        ).hits().hits().forEach { println(it.source()) }
    }

}
bookstorebookstore

ドキュメントは即時保存され、検索可能になるわけではない

elasitc - Refresh

ドキュメントはデフォルトではパフォーマンスの観点から非同期的に処理されるようで、 PUTPOST のレスポンスを受け取っただけでは対象のドキュメントが検索可能になったかどうかはわからない。 Refresh パラメータをtrueと設定することで即時検索可能となるが、パフォーマンスが低下する恐れがある。

bookstorebookstore

次のとおりにコードを修正したら期待したどおりの動作となった。

class ElasticsearchFistStepTest {

    @Test
    fun firstStep() {
        val esClient = run {
            val lowRestClient = RestClient.builder(HttpHost("localhost", 9200)).build()
            val transport = RestClientTransport(lowRestClient, JacksonJsonpMapper())
            ElasticsearchClient(transport)
        }

        // インデックスを作成する。
        esClient.indices().create { c -> c.index("demo-index") }

        // ドキュメントを作成する。
        // id を指定していないため、elasticsearchにより採番される。
        //
        // refresh を true とし直ちにプライマリ、レプリカシャードを更新することで後続でこのドキュメントを検索できるようにする。
        // テストコードのため即時更新しているがパフォーマンスの低下につながる可能性があるため本番などでは慎重に判断すること。
        // https://www.elastic.co/guide/en/elasticsearch/reference/8.0/docs-refresh.html
        esClient.index<Item> { c ->
            c.index("demo-index")
                .document(Item("name-1", "category-1", 100))
+              .refresh(Refresh.True)
        }

        // ドキュメントを検索する
        esClient.search(
            { _0 ->
                _0.index("demo-index").query { _1 ->
                    _1.term { _2 ->
                        _2.field("category.keyword").value("category-1")
                    }
                }
            },
            Item::class.java
        ).run {
            assertEquals(1, hits().hits().size)
            assertEquals(Item("name-1", "category-1", 100), hits().hits()[0].source())
        }
    }

}
このスクラップは2022/03/05にクローズされました