olivere / elastic

Deprecated: Use the official Elasticsearch client for Go at https://github.com/elastic/go-elasticsearch
https://olivere.github.io/elastic/
MIT License
7.4k stars 1.15k forks source link

question: filter fully formed query #421

Closed kmulvey closed 7 years ago

kmulvey commented 7 years ago

Please use the following questions as a guideline to help me answer your issue/question without further inquiry. Thank you.

Which version of Elastic are you using?

[ ] elastic.v2 (for Elasticsearch 1.x) [ ] elastic.v3 (for Elasticsearch 2.x) [x ] elastic.v5 (for Elasticsearch 5.x)

Please describe the expected behavior

Given a fully formed query as a string, add a filter field.

Please describe the actual behavior

Any steps to reproduce the behavior?

Is it possible to modify an already fully formed query to add a filter? I am building a proxy to ES and want to take a user's query and limit the results to what they are allowed to see. I cant make any assumptions about what the input query could be. A simple example:

GET /index/_search
{
  "from" : 0, "size" : 100,
  "query": {
    "match": {
      "name": "GERMANY"
    }
  }
}

GET /index/_search
{
  "from": 0,
  "size": 100,
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "GERMANY"
          }
        }
      ],
      "filter": [
        {
          "term": {
            "org_id": 115668
          }
        }
      ]
    }
  }
}
olivere commented 7 years ago

Elastic only contains a DSL for building the query, not for parsing it. So there's not general "Yes" for your answer.

But given the relatively strict and documented DSL syntax defined by Elasticsearch, there probably are ways to achieve what you're after. E.g. if you create a proxy, you could parse the body as you know it must be valid JSON and inject your filter.

For peeking into JSON, jsonq is nice. For injecting the filter, you probably can directly inject into the deserialized map[string]interface{}. Elastic is happy to take a map[string]interface{} and send it as serialized JSON; you can also use RawStringQuery for sending the request (but it's just the query part, not the whole body!). If you want to send your own body, you can use PerformRequest directly.

HTH.