2

I'm writing a Java application and use elastic search as database.

I'm looking for a way to write a "not-contains" query.

For Example I've got a field category with values:

  • Car
  • Bus
  • Train
  • Fastcar

Now I want to get all entries which not contains "fast" in their category.

How can I build a query like this? I have been looking around here but can't find anything.

Thanks in advance

So thanks to @James and @Bhavya Gupta I could update my query but it doesn't work as expected.

My query now is:

"query": {
        "bool": {
            "must": {
                "match_all": {}
            },
            "filter": {
                "bool": {
                    "must_not": [
                        {
                            "term": {
                                "BetriebsID": "Aufzug"
                            }
                        }   ]
                    }
                }
        }
    }

But the result still contains hits like this:

"hits": [
            "_source": {
                ...
                "FormNo": 9150520000000692,
                "CreatedTime": "2020-05-15T08:19:03.000Z",
                "templateId": "Aufzugsstoerung",
                "SYS_FORM_ID": "150520_000000692",
                "trecId": 151,
                "BetriebsID": "20200515_1019_Aufzugsstoerung",
                "displayName": "Aufzugsstörung",
                ...
            }
            }]

I also tried it with the wildcard query from James, with the same result.

3
  • 1
    did you get a chance to go through my answer, looking forward to get feedback from you :) Commented Sep 22, 2020 at 16:03
  • yes I did but i doesn't work for me. I updated my question. Please have a look. Commented Sep 23, 2020 at 9:25
  • so I get the query to work. The error was, there is a keyword-mapping on BetriebsId. So I need to filter for BetriebsId.keyword. Than the query works as expected Commented Sep 23, 2020 at 12:23

2 Answers 2

4

You can make use of Boolean Queries with must_not for the same. Kibana query would look like:

GET my_index/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "wildcard": {
            "category": {
              "value": "fast*"
            }
          }
        }
      ]
    }
  }
}

Sample Java Code:

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
                .query(QueryBuilders.boolQuery().mustNot(QueryBuilders.wildcardQuery("category", "fast*")));
        SearchRequest searchRequest = new SearchRequest("index_name");
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Sign up to request clarification or add additional context in comments.

Comments

3

Wildcard queries can also be used as suggested by @James, but it is not recommended to use Wildcard (especially at the beginning of search query), as it may affect the performance and slow down the search.

Adding a working example with index mapping, search query, and search result

Index Mapping:

{
    "settings": {
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "tokenizer": "my_tokenizer"
                }
            },
            "tokenizer": {
                "my_tokenizer": {
                    "type": "ngram",
                    "min_gram": 2,
                    "max_gram": 10,
                    "token_chars": [
                        "letter",
                        "digit"
                    ]
                }
            }
        },
        "max_ngram_diff": 50
    },
    "mappings": {
        "properties": {
            "category": {
                "type": "text",
                "analyzer": "my_analyzer",
                "search_analyzer": "standard"
            }
        }
    }
}

Search Query:

{
    "query": {
        "bool": {
            "must": {
                "match_all": {}
            },
            "filter": {
                "bool": {
                    "must_not": [
                        {
                            "term": {
                                "category": "fast"
                            }
                        }
                    ]
                }
            }
        }
    }
}

Search Result:

"hits": [
      {
        "_index": "stof_64009221",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "category": "car"
        }
      },
      {
        "_index": "stof_64009221",
        "_type": "_doc",
        "_id": "2",
        "_score": 1.0,
        "_source": {
          "category": "bus"
        }
      },
      {
        "_index": "stof_64009221",
        "_type": "_doc",
        "_id": "3",
        "_score": 1.0,
        "_source": {
          "category": "train"
        }
      }
    ]

1 Comment

I'm sorry but I marked James reply as solution. It seems that for my real-world queries the wildcard-query works and the Term-query does not. But I tried it in different ways because performance is very important to mo

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.