Skip to content

Conversation

@csh97
Copy link
Contributor

@csh97 csh97 commented Feb 9, 2024

Implements #116

Adds support for remaining join queries: has_parent, has_child and parent_id (https://www.elastic.co/guide/en/elasticsearch/reference/current/joining-queries.html)

Changes to note:

  • Moved nested query into join-queries file as Elasticsearch documentation groups it under join queries
  • Moved ScoreMode enum from inside nested query to join-queries file as has_parent and has_child use the same score modes
  • Changed filter source extension functions to extend on JsonDsl rather than SearchDsl so that they can be used for inner hits in parent and child queries
  • Added documentation for join queries (Left nested query as a TODO as I don't have any experience using nested queries)

has_parent

SearchDSL().apply {
        query = hasParent("parent") {
            query = matchAll()
            minChildren = 1
            maxChildren = 2
            scoreMode = ScoreMode.max
            ignoreUnmapped = true
            innerHits {
                filterSource("name")
                innerHitSize = 1
                name = "adfa"
                sort { add("a") }
            }
        }
    }.json(pretty = true).let { println(it) }

Produces:

{
  "query": {
    "has_parent": {
      "parent_type": "parent",
      "query": {
        "match_all": {
        }
      },
      "min_children": 1,
      "max_children": 2,
      "score_mode": "max",
      "ignore_unmapped": true,
      "inner_hits": {
        "_source": [
          "name"
        ],
        "size": 1,
        "name": "adfa",
        "sort": [
          {
            "a": {
              "order": "DESC"
            }
          }
        ]
      }
    }
  }
}

has_child

SearchDSL().apply {
        query = hasChild("child") {
            query = matchAll()
            minChildren = 1
            maxChildren = 2
            scoreMode = ScoreMode.max
            ignoreUnmapped = true
            innerHits {
                filterSource("name")
                innerHitSize = 1
                name = "adfa"
                sort { add("a") }
            }
        }
    }.json(pretty = true).let { println(it) }

Produces:

{
  "query": {
    "has_child": {
      "type": "child",
      "query": {
        "match_all": {
        }
      },
      "min_children": 1,
      "max_children": 2,
      "score_mode": "max",
      "ignore_unmapped": true,
      "inner_hits": {
        "_source": [
          "name"
        ],
        "size": 1,
        "name": "adfa",
        "sort": [
          {
            "a": {
              "order": "DESC"
            }
          }
        ]
      }
    }
  }
}

parent_id

SearchDSL().apply {
        query = parentId(type = "child", id = "123") {
            ignoreUnmapped = true
        }
    }.json(pretty = true).let { println(it) }

Produces:

{
  "query": {
    "parent_id": {
      "type": "child",
      "id": "123",
      "ignore_unmapped": true
    }
  }
}


fun QueryClauses.nested(block: NestedQuery.() -> Unit): NestedQuery {
val q = NestedQuery()
block.invoke(q)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor - direct call can be used here and below

Suggested change
block.invoke(q)
block(q)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used invoke() as it seems like most of the project is using it over direct call and I wanted to keep with convention of the project. But I am also happy to change to direct call

@jillesvangurp
Copy link
Owner

Nice. Also thanks for documenting this.

@jillesvangurp jillesvangurp merged commit c40db35 into jillesvangurp:master Feb 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants