I'm seriously struggling with a query in Elastic search so i'm hoping someone here can help me.
So I have an Index in elastic search which stores some basic info on a user. Then I have my Spring Boot API which allows a client to search on said index.
In my app, when a user signs up they get to choose a displayname on the site. Now when they type out a display name I want to be able to check elastic and tell them if its taken or not.
However, where I'm struggling is, say I have One user in my Index with the DisplayName of "John Boy", now user two signs up and wants the display name "Boy". When I do a search to see if "Boy" is taken, I get back "John Boy". I want it so the query tells me if "Boy" is free and not care if "John Boy" is taken.
I thought I was just getting my head around ES but maybe not, I was under the impression that the field (see index mapping below) keyword I could do a term search and get back the exact match?
Below I've included my Pojo and my ES index mapping. Please if anyone can help me....thanks for reading:
Search Method
public long checkUserNameAvailability(String query) {
QueryBuilder matchSpecificFieldQuery= QueryBuilders
.termQuery("displayName", query);
Query searchQuery = new NativeSearchQueryBuilder()
.withFilter(matchSpecificFieldQuery)
.build();
SearchHits<UserProfile> searchSuggestions =
elasticsearchOperations.search(searchQuery,
UserProfile.class,
IndexCoordinates.of(elasticUserIndex));
List<UserProfile> suggestions = new ArrayList<>();
return searchSuggestions.getTotalHits();
}
Pojo
@Getter
@Setter
@Document(indexName = "userprofiles")
public class UserProfile {
@Field(type = FieldType.Text, name = "userId")
private String userId;
@Field(type = FieldType.Keyword, name = "displayName")
private String displayName;
@Field(type = FieldType.Text, name = "name")
private String name;
}
ES Mapping
{
"userprofiles": {
"mappings": {
"properties": {
"displayName": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
},
"name": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
},
"userId": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
}
}
}
}
}
Side note: I'm using Spring boot version 2.4.3
And
compile('org.springframework.boot:spring-boot-starter-data-elasticsearch')
compile group: 'org.springframework.data', name: 'spring-data-elasticsearch', version: '4.1.5'
Once again many thanks
Maybe you should use keyword query, because 'displayName' field type is text, it will be analyzer in both query and index.
QueryBuilder matchSpecificFieldQuery= QueryBuilders
.termQuery("displayName.keyword", query);
I think you shuld reconsider the type of query you are using. Try using a simple match on the .keyword field.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With