Searching for a few fields from Set Collection


(Nikita Krasnov) #1

I have logs with different levels. For example: "DEBUG" and "INFO".
What if I want to search for "DEBUG" and "INFO" simultaniously?

for example, in json request should be set(Java collection) of levels:

{
	"level": ["DEBUG", "INFO"]
}

And in response I want to get all logs with "DEBUG" and "INFO".

I have such thoughts, but it isn't work:

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder bqb = QueryBuilders.boolQuery();
if (esLogRequest.getLevels() != null) {
            Iterator<String> iterator = esLogRequest.getLevels().iterator();
            while (iterator.hasNext()) {
                bqb.filter(QueryBuilders.termQuery("level", iterator.next()));
            }
        }

where esLogRequest.getLevels() returns set of Strings.


(David Pilato) #2

This works well:

DELETE test 
PUT test/doc/1
{
	"level": ["DEBUG", "INFO"]
}
PUT test/doc/2
{
	"level": ["ERROR", "INFO"]
}
PUT test/doc/3
{
	"level": ["INFO"]
}
GET test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "level": {
              "value": "debug"
            }
          }
        },        {
          "term": {
            "level": {
              "value": "info"
            }
          }
        }
      ]
    }
  }
}

And gives:

{
  "took": 6,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.5753642,
    "hits": [
      {
        "_index": "test",
        "_type": "doc",
        "_id": "1",
        "_score": 0.5753642,
        "_source": {
          "level": [
            "DEBUG",
            "INFO"
          ]
        }
      }
    ]
  }
}

First thing to do is to reproduce the problem with just a script like I did. Then try to understand what is wrong.
Here, I'm almost sure (but you did not share your mapping), that you are searching on a text field with default analyzer, using a term query with uppercase terms like DEBUG and INFO. Which is not going to work.


Elasticsearch - searching with "keyword" type don't work
(Nikita Krasnov) #3

Thank you. That's not really I've wanted.
Firstly, I want to put documents only with one level. For, example:doc{1} will have only "INFO" and doc{2} will have only "DEBUG".
But in request I want to send Set(Java collection) of documents. For example: give me all documents where level is "INFO" or "DEBUG". And in result I want to receive doc{1} and doc{2}.


(Nikita Krasnov) #4

For such case, I think, I can use SpanOrQueryBuilder:
https://www.elastic.co/guide/en/elasticsearch/reference/6.1/query-dsl-span-or-query.html
But, I'm not really know how to write it in Java.


(Nikita Krasnov) #5

I've solved question in such way:

if (esLogRequest.getLevels() != null) {
            Iterator<String> iterator = esLogRequest.getLevels().iterator();
            int counter = 0;
            SpanOrQueryBuilder spanOrQueryBuilder = null;
            while (iterator.hasNext()) {
                if (counter == 0) {
                    spanOrQueryBuilder = new SpanOrQueryBuilder(QueryBuilders.
                            spanTermQuery("level", iterator.next()));
                } else {
                    spanOrQueryBuilder.addClause(QueryBuilders.
                            spanTermQuery("level", iterator.next()));
                }
                counter++;
            }
            bqb.filter(spanOrQueryBuilder);
        }

(system) #6

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.