Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
13 posts found #arama
From Elasticsearch 8 to 9.x and OpenSearch 3: What's New, What Was Removed and Which to Choose
Database PART 13

From Elasticsearch 8 to 9.x and OpenSearch 3: What's New, What Was Removed and Which to Choose

You upgrade from Elasticsearch 8 to 9.x by moving to the latest 8.19 first, clearing deprecation warnings and taking a snapshot; OpenSearch 3 shares the core but goes its own way and needs its own .NET client. With real output: parameters that warn on 8.19 returning 400 on 9.5, the deprecation API, opening 8.19 data on 9.5 with no way back, LOOKUP JOIN, the Elastic client getting a 406 from OpenSearch, the same search with OpenSearch.Client, and a decision table.

14 Nov 2026 13 min 18
Running Elasticsearch in Production: Security, Capacity, Monitoring and Common Problems
Database PART 12

Running Elasticsearch in Production: Security, Capacity, Monitoring and Common Problems

Running Elasticsearch in production means a closed network, TLS, per-application API keys granted on an alias, at least three master-eligible nodes, watched heap and disk thresholds, and a measured restore plan. With real output: a self-signed CA with a fingerprint in the .NET client, DLS/FLS returning 403 on a basic license, the flood-stage watermark stopping writes, a circuit breaker error, search text in the slow log, SLM, and restore versus reindexing from SQL Server.

14 Nov 2026 13 min 13
Index Lifecycle: Zero-Downtime Reindex with Aliases, Index Templates, Shard Sizing and ILM
Database PART 11

Index Lifecycle: Zero-Downtime Reindex with Aliases, Index Templates, Shard Sizing and ILM

If the application talks to an alias instead of a real index name, a mapping change is not an outage but a new index from a template, a _reindex and one atomic _aliases request. With real output: remove_index on the first switch, a half-applied alias request and must_exist, version_type external, replaying changes that arrive during the reindex from a checkpoint, require_alias, choosing the shard count, ILM with a data stream, and snapshot/restore.

14 Nov 2026 16 min 16
Elastic.Clients.Elasticsearch 9 in .NET: the Typed API, Fluent vs Object Initializer, Serialization, Error Handling and Testing
Database PART 10

Elastic.Clients.Elasticsearch 9 in .NET: the Typed API, Fluent vs Object Initializer, Serialization, Error Handling and Testing

With Elastic.Clients.Elasticsearch 9 you register the client as a DI singleton with validated options, gather queries in a testable builder, and test behavior against a real Elasticsearch with Testcontainers. With real output: a descriptor search skipping the index and going to /_search, Insert instead of Add in the source serializer, server, transport and 429 errors, calling ES|QL with a string and with LINQ, and the regression test that catches post 9's bug.

14 Nov 2026 13 min 15
Aggregations and Faceted Search: terms, range, date_histogram, nested and post_filter
Database PART 09

Aggregations and Faceted Search: terms, range, date_histogram, nested and post_filter

In faceted search the text goes into the query, selected filters go into post_filter, and each facet is wrapped with every other selected filter but its own; otherwise a selected filter empties its own facet. With real output: terms, range, date_histogram, avg and cardinality, nested with reverse_nested, Bookstore's faceted /books/search endpoint, terms counts going wrong on 5 shards and doc_count_error_upper_bound, and the same report in ES|QL.

14 Nov 2026 12 min 13
Autocomplete and Search-as-You-Type: edge_ngram, search_as_you_type and the Completion Suggester
Database PART 08

Autocomplete and Search-as-You-Type: edge_ngram, search_as_you_type and the Completion Suggester

Suggest-as-you-type in Elasticsearch needs a field that indexes word beginnings: edge_ngram, search_as_you_type or the completion suggester; for Bookstore we chose edge_ngram, which also suggests from middle words and can be filtered. With real output: "kür" finding Kürk Mantolu Madonna, analyzer order, the or trap of bool_prefix, mandatory completion contexts, field sizes with _disk_usage, and a /books/suggest endpoint with _source filtering, collapse and Output Cache.

14 Nov 2026 12 min 14
Relevance Tuning: Field Boosts, function_score, Fuzzy Search, Highlighting and "Did You Mean?"
Database PART 07

Relevance Tuning: Field Boosts, function_score, Fuzzy Search, Highlighting and "Did You Mean?"

You tune search ranking by measuring it with the _rank_eval API against a set of queries and expected results, not by guessing. With real output: an author boost, fuzziness and a phrase clause that raise nDCG@5 from 0.905 to 0.979; tie_breaker and a harsh function_score that made it worse; rescore, highlighting with the html encoder for XSS-safe rendering, and "did you mean?" with the phrase suggester.

14 Nov 2026 14 min 15
Query DSL 1: match, multi_match, term, bool Queries, Filter Context and Pagination
Database PART 06

Query DSL 1: match, multi_match, term, bool Queries, Filter Context and Pagination

Send what the user typed to text fields with match, exact values to keyword fields with term, and every clicked filter to the bool query's filter section; a filter in must inflates scores and loses caching. With real output: multi_match's best_fields, most_fields and cross_fields types, nested author search, Bookstore's /books/search endpoint, the 10,000 limit of from/size, search_after with a PIT, and simple_query_string instead of query_string.

14 Nov 2026 15 min 10
Getting Data into Elasticsearch: the Bulk API, Refresh, Versioning and Syncing with SQL Server
Database PART 05

Getting Data into Elasticsearch: the Bulk API, Refresh, Versioning and Syncing with SQL Server

You write data to Elasticsearch with the Bulk API, not one document at a time; but bulk is not atomic, a written document is not searchable until a refresh, and dual writes from SQL Server silently lose data. With real output: IndexAsync versus bulk, BulkAll and refresh_interval, per-item bulk failures, if_seq_no and external versions, a BackgroundService polling with rowversion, and MIN_ACTIVE_ROWVERSION so open transactions are not missed.

14 Nov 2026 15 min 12
Analyzers and Turkish: Tokenizers, Token Filters, the turkish Analyzer, ASCII Folding and Synonyms
Database PART 04

Analyzers and Turkish: Tokenizers, Token Filters, the turkish Analyzer, ASCII Folding and Synonyms

Turkish search in Elasticsearch is not fixed by the built-in turkish analyzer as is: the apostrophe and Turkish lowercase filters help, but the Snowball stemmer reduces "İnce" to "i" and "kasaba" to "kasap"; the fix is keyword_marker, a sub-field without Turkish characters and querying several fields together. With real output: the analyzer chain, the stemmer's limits, Turkish sorting with ICU and the Synonyms API without reindexing.

14 Nov 2026 13 min 11
Elasticsearch Mapping: text vs keyword, Multi-Fields, Dynamic Mapping, nested and Why Mappings Can't Change
Database PART 03

Elasticsearch Mapping: text vs keyword, Multi-Fields, Dynamic Mapping, nested and Why Mappings Can't Change

In Elasticsearch the mapping sets each field's type and how it is indexed; leave it to guessing and an ISBN becomes a number, a decimal price an integer, and you get wrong results without an error, so a production index needs dynamic: strict and a hand-written mapping. With real output: dynamic mapping traps, text vs keyword, title.keyword and title.folded multi-fields, scaled_float prices, object vs nested with a nested query in .NET, flattened, immutable mappings and the field limit.

14 Nov 2026 15 min 17
Elasticsearch Lab: start-local, Kibana Dev Tools, Cluster Health and the First .NET Connection
Database PART 02

Elasticsearch Lab: start-local, Kibana Dev Tools, Cluster Health and the First .NET Connection

For a local Elasticsearch lab, Elastic's start-local script or a small Docker Compose file with security on and a pinned version is enough; the application connects not as elastic but with an API key limited to its own indices and a singleton ElasticsearchClient. With real output: what start-local does, a service account token for Kibana, yellow health and allocation explain, a scoped key's 403s, the first IndexAsync/GetAsync with Elastic.Clients.Elasticsearch 9.5 and error cases.

14 Nov 2026 14 min 13
Blog Map