Case insensitive searching in elasticsearch 6.1.2 - java

I was trying to search the following case
I want to search a name that ends with the particular word. For example:
name : group Test
name : group test
name : group test org
Here is my wild card query
"bool" : {
"must" : [
{
"wildcard" : {
"name.keyword"" : {
"wildcard" : "*test",
"boost" : 1.0
}
}
}
]
}
It returns me "group test" for case sensitive search
But I need to get both "group Test" and "group test" for case-insensitive search.
my mapping as follows:
"name":{
"type":"text",
"fielddata":true
"fields":{
"keyword":{
"type":"keyword"
}
}
}
Can anyone help me to find out queries in elasticsearch java api or any other way to search it.
Elastic search version 6.1.2
Any help is really appreciated.

Unfortunately there is no direct way to do this with ES configuration as keyword type does not have the analyzer property but I found a workaround. Please take a look on this solution:
PUT test
{
"settings": {
"analysis": {
"analyzer": {
"folding": {
"tokenizer": "standard",
"filter": [ "lowercase", "asciifolding" ]
}
},
"normalizer": {
"lowerasciinormalizer": {
"type": "custom",
"filter": [ "lowercase", "asciifolding" ]
}
}
}
},
"mappings": {
"_default_": {
"dynamic_templates": [
{
"string_as_keyword": {
"match_mapping_type": "string",
"match": "*_k",
"mapping": {
"type": "keyword",
"normalizer": "lowerasciinormalizer"
}
}
}
]
}
}
}
PUT test/1/123
{
"str_k" : "string âgáÈÒU is cool"
}
GET test/_search
{
"query": {
"wildcard": {
"str_k": "*agaeou*"
}
}
}

Related

Elasticsearch SELECT * FROM IP="1.1.1.1" AND NAME="ETH1/10"

I am ne on elastichSearch. i am trying the exact match and and operation. I tried so many ways but all the time the response is mess for me. It is like fuzzy match. I need exact match as RDBMS
SELECT * FROM IP="1.1.1.1" AND NAME="ETH1/10"
Thanks in advance.
If You need the exact match than instead of match query use term query
Adding a working example
Index mapping
{
"mappings": {
"properties": {
"name": {
"type": "keyword"
},
"ip" :{
"type" : "ip"
}
}
}
}
Index sample doc
{
"name" : "ETH1/10",
"ip" : "1.1.1.1"
}
And search query
{
"query": {
"bool": {
"filter": [ --> use `filter` as pointed by #Val in the comment.
{
"term": {
"ip": "1.1.1.1"
}
},
{
"term": { --> `term` query for exact match.
"name": "ETH1/10"
}
}
]
}
}
}
And search result
"hits": [
{
"_index": "65167713",
"_type": "_doc",
"_id": "1",
"_score": 0.0,
"_source": {
"name": "ETH1/10",
"ip": "1.1.1.1"
}
}
]
How about this?
{
"query":{
"bool":{
"must":[
{
"match":{
"IP":"1.1.1.1"
}
},
{
"match":{
"NAME":"ETH1/10"
}
}
]
}
}
}
}

Elastic Search wildcard query not working with case insensitive ( for lower case)

I am trying to fetch records from elasticsearch using wildcard queries.
Please find the below query
get my_index12/_search
{
"query": {
"wildcard": {
"code.keyword": {
"value": "*ARG*"
}
}
}
}
It's working and giving expected results for the above query., but it is not working for the lower case value.
get my_index12/_search
{
"query": {
"wildcard": {
"code.keyword": {
"value": "*Arg*"
}
}
}
}
Try Following:
Mapping:
PUT my_index12
{
"settings": {
"analysis": {
"analyzer": {
"custom_analyzer": {
"type": "custom",
"tokenizer": "whitespace",
"char_filter": [
"html_strip"
],
"filter": [
"lowercase",
"asciifolding"
]
}
}
}
},
"mappings": {
"doc": {
"properties": {
"code": {
"type": "text",
"analyzer": "custom_analyzer"
}
}
}
}
}
Then Run Query String Query
GET my_index12/_search
{
"query": {
"query_string": {
"default_field": "code",
"query": "AB\\-7000*"
}
}
}
It will also work for ab-7000*
Let me know if it works for you.
You have to normalize your keyword field:
ElasticSearch normalizer
Something like (from documentation):
PUT index
{
"settings": {
"analysis": {
"normalizer": {
"my_normalizer": {
"type": "custom",
"char_filter": [],
"filter": ["lowercase", "asciifolding"]
}
}
}
},
"mappings": {
"_doc": {
"properties": {
"foo": {
"type": "keyword",
"normalizer": "my_normalizer"
}
}
}
}
}
UPDATE
Some additional info:
Only parts of the analysis chain that operate at the character level are applied. So for instance, if the analyzer performs both lowercasing and stemming, only the lowercasing will be applied: it would be wrong to perform stemming on a word that is missing some of its letters.
By setting analyze_wildcard to true, queries that end with a * will be analyzed and a boolean query will be built out of the different tokens, by ensuring exact matches on the first N-1 tokens, and prefix match on the last token.

Array search in elasticsearch

I have 3 document,
{
"category":[{"id":"1"},{"id":"2"},{"id":"3"}]
}
{
"category":[{"id":"1"},{"id":"4"}]
}
{
"category":[]
}
How I can find document which have category.id in (2,3) like mysql,
also which type of DSL query I need to use in java api querybuilder
You can use the bool query with should clause to find all documents which contain either of the requested ids. Here is how the Query DSL would like
{
"query": {
"bool": {
"should": [
{"term": {
"category.id": {
"value": "2"
}
}},
{"term": {
"category.id": {
"value": "3"
}
}
}
]
}
}
}
Here's how you would use the Java API
QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("category.id", "2"))
.should(QueryBuilders.matchQuery("category.id", "1"));
If the id field is not-analysed, you can also use the terms query. More info here https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html
Here's how your query should look like:
{
"query": {
"bool": {
"filter": [
{
"term": {
"category.id": "1"
}
},
{
"term": {
"category.id": "2"
}
}
]
}
}
}
Like this:
{
"filter": {
"terms": {
"category.id": ["2", "3"]
}
}
}

"MapperParsingException[Analyzer [second] not found for field [Name]]"

I have created an index in Elasticsearch with the following settings:
{
"my_index" : {
"aliases" : { },
"mappings" : { },
"settings" : {
"index" : {
"creation_date" : "1461229073677",
"uuid" : "7-TECarfRs6XO8yZE7SeWA",
"number_of_replicas" : "1",
"number_of_shards" : "5",
"version" : {
"created" : "1040599"
},
"settings" : {
"analysis" : {
"analyzer" : {
"second" : {
"type" : "custom",
"filter" : [ "lowercase", "synonym" ],
"tokenizer" : "standard"
}
},
"filter" : {
"synonym" : {
"type" : "synonym",
"synonyms" : [ "i pad => ipad", "smart phone => smartphone" ]
}
}
}
}
}
},
"warmers" : { }
}
}
Now what I m trying to do is to set the mappings using the following code:
PutMapping putMapping = new PutMapping.Builder(
"my_index",
"my_index_type",
"{ \"properties\" : { \"Name\" : {\"type\" : \"string\", \"analyzer\" : \"second\"} } }"
).build();
JestResult result = client.execute(createIndex);
result = client.execute(putMapping);
EDIT
The code I m using to create the index is:
CreateIndex createIndex = new CreateIndex.Builder(indexName)
.settings(
ImmutableSettings.builder()
.loadFromClasspath(
"settings.json"
).build().getAsMap()
).build();
JestResult result = client.execute(createIndex);
and the settings.json looks like this:
{
"settings": {
"analysis": {
"analyzer": {
"second": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"synonym"
]
}
},
"filter": {
"synonym" : {
"type" : "synonym",
"synonyms" : [
"i pad => ipad",
"smart phone => smartphone",
"i phone => iphone"
]
}
}
}
}
}
However I keep getting the following error:
"MapperParsingException[Analyzer [second] not found for field [message]]"
I am able to set the mapping if I remove the "analyzer". So it seems that I have two times the "settings" section, but no matter how I structure the "settings.json" file I keep getting these two sections. I looked into the examples specified in JEST page but didnt help me. https://github.com/searchbox-io/Jest/blob/master/jest/README.md
Any ideas guys?
The settings you're using are not properly defined, i.e. you have two imbricated settings sections, the index settings should look like this instead:
{
"my_index": {
"aliases": {},
"mappings": {},
"settings": {
"index": {
"number_of_replicas": "1",
"number_of_shards": "5"
},
"analysis": {
"analyzer": {
"second": {
"type": "custom",
"filter": [
"lowercase",
"synonym"
],
"tokenizer": "standard"
}
},
"filter": {
"synonym": {
"type": "synonym",
"synonyms": [
"i pad => ipad",
"smart phone => smartphone"
]
}
}
}
},
"warmers": {}
}
}
UPDATE
Your settings.json file simply needs to contain the following:
{
"analysis": {
"analyzer": {
"second": {
"type": "custom",
"filter": [
"lowercase",
"synonym"
],
"tokenizer": "standard"
}
},
"filter": {
"synonym": {
"type": "synonym",
"synonyms": [
"i pad => ipad",
"smart phone => smartphone"
]
}
}
}
}

Elasticsearch and mongodb, partial search not working

This is my location Collection in mongodb:
{ "_id" : ObjectId("5270d36f28f31fd8fa016441"), "stateName" : "A5", "cityName" : "ABCNEW2" }
{ "_id" : ObjectId("5270d37328f31fd8fa016442"), "stateName" : "A5", "cityName" : "ABC" }
{ "_id" : ObjectId("5270d37b28f31fd8fa016443"), "stateName" : "65", "cityName" : "ABCRW" }
I created one index using elastic Search:
POST /bwitter
{"index":
{ "number_of_shards": 1,
"analysis": {
"filter": {
"mynGram" : {"type": "nGram", "min_gram": 2, "max_gram": 10}
},
"analyzer": { "a1" : {
"type":"custom",
"tokenizer": "standard",
"filter": ["lowercase", "mynGram"]
}
}
}
}
}
I created one mapping using elastic search:
PUT /bwitter/bweet/_mapping
{
"bweet" : {
"index_analyzer" : "a1",
"search_analyzer" : "standard",
"properties" : {
"stateName": {"type":"string", "analyzer":"standard"},
"cityName" : {"type" : "string" }
}
}
}
Created river as follows:
PUT /_river/mongodb/_meta
{
"type": "mongodb",
"mongodb": {
"db": "rakeshdb",
"collection": "locations"
},
"index": {
"name": "locations",
"type": "bweet"
}
}
If, I query GET /locations/_search?q=ABC, I get only one record (Full word search is happening, not happening for the partial word)
I almost spend a whole day on this but not able to solve this. Where am I going wrong?
I guess that it should be:
PUT /_river/mongodb/_meta
{
"type": "mongodb",
"mongodb": {
"db": "rakeshdb",
"collection": "locations"
},
"index": {
"name": "bwitter",
"type": "bweet"
}
}

Categories