# Searching for a few fields from Set Collection

**URL:** <https://discuss.elastic.co/t/searching-for-a-few-fields-from-set-collection/117189>\
**Category:** Elasticsearch\
**Created:** [January 26, 2018, 12:27pm UTC](https://discuss.elastic.co/t/searching-for-a-few-fields-from-set-collection/117189 "2018-01-26T12:27:40Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nikita\_Krasnov](https://avatars.discourse-cdn.com/v4/letter/n/53a042/32.png) [@Nikita\_Krasnov](https://discuss.elastic.co/u/Nikita_Krasnov)\
**Post date:** [January 26, 2018, 12:27pm UTC](https://discuss.elastic.co/t/searching-for-a-few-fields-from-set-collection/117189/1 "2018-01-26T12:27:40Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [January 26, 2018, 12:51pm UTC](https://discuss.elastic.co/t/searching-for-a-few-fields-from-set-collection/117189/2 "2018-01-26T12:51:29Z")

</div>

This works well:

```auto
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:

```auto
{
  "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.

---

<div class="post-metadata">

**Author:** ![Nikita\_Krasnov](https://avatars.discourse-cdn.com/v4/letter/n/53a042/32.png) [@Nikita\_Krasnov](https://discuss.elastic.co/u/Nikita_Krasnov)\
**Post date:** [January 29, 2018, 7:45am UTC](https://discuss.elastic.co/t/searching-for-a-few-fields-from-set-collection/117189/3 "2018-01-29T07:45:58Z")

</div>

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}`.

---

<div class="post-metadata">

**Author:** ![Nikita\_Krasnov](https://avatars.discourse-cdn.com/v4/letter/n/53a042/32.png) [@Nikita\_Krasnov](https://discuss.elastic.co/u/Nikita_Krasnov)\
**Post date:** [January 29, 2018, 9:06am UTC](https://discuss.elastic.co/t/searching-for-a-few-fields-from-set-collection/117189/4 "2018-01-29T09:06:56Z")

</div>

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](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.

---

<div class="post-metadata">

**Author:** ![Nikita\_Krasnov](https://avatars.discourse-cdn.com/v4/letter/n/53a042/32.png) [@Nikita\_Krasnov](https://discuss.elastic.co/u/Nikita_Krasnov)\
**Post date:** [January 29, 2018, 2:09pm UTC](https://discuss.elastic.co/t/searching-for-a-few-fields-from-set-collection/117189/5 "2018-01-29T14:09:10Z")

</div>

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);
        }
```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [February 26, 2018, 2:09pm UTC](https://discuss.elastic.co/t/searching-for-a-few-fields-from-set-collection/117189/6 "2018-02-26T14:09:11Z")

</div>

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