jillesvangurp / kt-search

Multi platform kotlin client for Elasticsearch & Opensearch with easily extendable Kotlin DSLs for queries, mappings, bulk, and more.
MIT License
107 stars 22 forks source link

Add support for join field mappings #112

Closed csh97 closed 8 months ago

csh97 commented 8 months ago

Add support for join field types in index mappings

See Elasticsearch documentation: https://www.elastic.co/guide/en/elasticsearch/reference/current/parent-join.html

The documentation has the following example of a simple join field:

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "my_id": {
        "type": "keyword"
      },
      "my_join_field": { 
        "type": "join",
        "relations": {
          "question": "answer" 
        }
      }
    }
  }
}

With the added JoinDefinition and join() you can now replicate this:

IndexSettingsAndMappingsDSL().apply {
        mappings {
            join("my_join_field") {
                relations("question" to listOf("answer"))
            }
        }
    }.json(pretty = true).let(::println)

This produces:

{
  "mappings": {
    "properties": {
      "my_join_field": {
        "type": "join",
        "relations": {
          "question": [
            "answer"
          ]
        }
      }
    }
  }
}

The only difference here is question is always a list even if there is only 1 value, as far as I'm aware this shouldn't be a problem

The documentation also has a slightly more complex example with multiple levels of relation:

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "my_join_field": {
        "type": "join",
        "relations": {
          "question": ["answer", "comment"],  
          "answer": "vote" 
        }
      }
    }
  }
}

This can also be replicated like so:

 IndexSettingsAndMappingsDSL().apply {
        mappings {
            join("my_join_field") {
                relations("question" to listOf("answer", "comment"), "answer" to listOf("vote"))
            }
        }
    }.json(pretty = true).let(::println)

Which produces:

{
  "mappings": {
    "properties": {
      "my_join_field": {
        "type": "join",
        "relations": {
          "question": [
            "answer", 
            "comment"
          ],
          "answer": [
            "vote"
          ]
        }
      }
    }
  }
}
jillesvangurp commented 8 months ago

Awesome. I think you would also need the related queries and aggrgegation support to use this. But that can be done later with another PR if you feel up to it.

csh97 commented 8 months ago

My current use case is just for create indices and insert data, so I dont need the queries right now. However, you are right it would be great if the library supported it. I'm happy to have a look at adding support for this though

jillesvangurp commented 8 months ago

Thanks for this. I'll merge this.