Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested Sub-query does not generate correct elastic search syntax. #266

Open
vinay11283 opened this issue Apr 16, 2020 · 5 comments
Open
Labels

Comments

@vinay11283
Copy link

vinay11283 commented Apr 16, 2020

bodybuilder()
	.query('term', 'field', 'something')
       .andQuery('bool', (q) => {
     	return q.query('term', 'obj1.color', 'blue')
  	})
        .build()

generates bool.query which is not valid as per ES
[bool] query does not support [query]

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "field": "something"
          }
        },
        {
          "bool": {
            "query": {
              "term": {
                "obj1.color": "blue"
              }
            }
          }
        }
      ]
    }
  }
}

This is just simplistic scneario, I genuinely have some subqueries wiith nested path's as well which does not work. I can come up with better example if this does not make sense.

Please advise if there is a workaround I can apply ?

@danpaz
Copy link
Owner

danpaz commented Apr 16, 2020

@vinay11283 I'm not sure what you're trying to query for, but can't you just do

bodybuilder()
	.query('term', 'field', 'something')
        .query('term', 'obj1.color', 'blue')
        .build()

@vinay11283
Copy link
Author

@danpaz Thanks for your response. Sorry, I should have come up with a better example. I thought I would reporduce with a simple example but that was not a good choice.

Scenario: transactionId OR (firstName AND lastName) where firstName and lastName are nested fields in path

Here is how I construct it.

bodybuilder()
        .orQuery('match', 'transactionid', '1234')
        .orQuery('bool', oq=>{
            oq.andQuery('nested', 'path','application.account.person', nq=>{
              nq.andQuery('term', 'firstName', 'John')
              nq.andQuery('term', 'lastName', 'Doe')
              return nq
            })
          return oq
		})
        .build()

output 

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "transactionid": "1234"
          }
        },
        {
          "bool": {
            "query": {
              "nested": {
                "path": "application.account.person",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "term": {
                          "firstName": "John"
                        }
                      },
                      {
                        "term": {
                          "lastName": "Doe"
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        }
      ]
    }
  }
}

As you can see there is a bool>query 

Now as soon as I include another non-nested field, in the sub query it generates it fine.
transactionId OR (firstName AND lastName AND dateOfBirth ) where firstName and lastName are nested fields in path

bodybuilder()
        .orQuery('match', 'transactionid', '1234')
        .orQuery('bool', oq=>{
            oq.andQuery('nested', 'path','application.account.person', nq=>{
              nq.andQuery('term', 'firstName', 'John')
              nq.andQuery('term', 'lastName', 'Doe')
              return nq
            })
           oq.andQuery('term', 'dateOfBirth', '1900-01-01') 
          return oq
		})
        .build()

generates fine

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "transactionid": "1234"
          }
        },
        {
          "bool": {
            "must": [
              {
                "nested": {
                  "path": "application.account.person",
                  "query": {
                    "bool": {
                      "must": [
                        {
                          "term": {
                            "firstName": "John"
                          }
                        },
                        {
                          "term": {
                            "lastName": "Doe"
                          }
                        }
                      ]
                    }
                  }
                }
              },
              {
                "term": {
                  "dateOfBirth": "1900-01-01"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

@ferronrsmith
Copy link
Collaborator

ferronrsmith commented Apr 17, 2020

That's a known-issue. You can't have a single level nesting. If you think about it, it's redundant. It can be brought up a level.

@johannes-scharlach
Copy link
Collaborator

This sounds like the issue that #144 is trying to fix – however we didn't merge that PR since it would be a breaking change.

Furthermore most use cases can use the alternative described in #142: You can use filter instead of query and it will work without issue.

@qdelettre
Copy link

@johannes-scharlach Using filter instead of query will work, but filter and query have a different behavior regarding scoring (https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-filter-context.html).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants