Implement Suggestions & Spell check in full-text search Using Query builder in AEM - full-text-search

While implementing full-text search Using Query builder in AEM-6.4, I need to add feature for spell check and suggestion.
Is there any way to implement this using predicate map properties in Query builder, Indexing etc
Updated:
Code snippet -
#Inject
private Suggester suggester;
final String[] suggetions = suggester.getSuggestions(session, "searchGlobal", queryString, true);
final String spellCheck = suggester.spellCheck(session, queryString);
suggetions - is returning empty value &
suggester.spellCheck(session, queryString) - is throwing Nullpointer Exception

AEM internally uses Jackrabbit Oak JCR implementation, which uses lucene indexing for repository.
If we look at Jackrabbit Oak Lucene Index documentation. We would need to do 2 steps
Create required index
Use query, for example below to use the suggestion index created above
SELECT rep:suggest() FROM [nt:base] WHERE SUGGEST('test') AND ISDESCENDANTNODE('/a/b')
Similar way spell check can be also implemented, would just need property configured in index accordingly.

Related

Changing the token length of Spring Boot Elasticsearch pattern matching size

I am using Spring Boot and Elasticsearch and I am trying to use three character searches but the searches only match on five characters or more.
If I have a user name of 'Bob Smith' I can find the match searching for 'Smith' but searching for 'Bob' does not find a match.
I suspect this is something that needs to be changed in my class ''SearchMappingConfig implements HibernateOrmSearchMappingConfigurer'' but I can't find any information about changing the size of the tokens needed to successfully match a result.
My ''#Entity'' tables have ''#FullTextField(analyzer = "english")'' annotations on the fields I want included in the token searches.
How do I change the length of the search match?
Ideally I would like any three letters to form a match, so a search for 'Ron' would match 'Ronald' and 'Laronda'
Elasticsearch 7.14
Spring Boot 2.7.6
I have been reading Spring Boot and Elasticsearch documentation but cannot find any information about changing the match length.
Hibernate is able to use an Elasticsearch or Lucene client. Our existing project uses Lucene and it would have been a large undertaking to replace that.
The recommended solution is to create new analyzers so that incoming data creates smaller tokens, I didn't want to change analyzers on my existing database.
A lot of the documentation I was able to find pointed to using the Elasticsearch query builder or the Hibernate 5 method of using a wildcard.
I tested our Elasticsearch and found that the wildcard solution would work.
I ended up using the Hibernate 6 method for wildcard searching and it works well.
SearchResult<DataClass> result = searchSession.search(DataClass.class)
.where(f -> f.wildcard()
.fields(
"firstname",
"lastname",
"username",
"currentLegalName")
.matching("*"+searchText.toLowerCase()+"*"))
.fetch(10);
long totalHitCount = result.total().hitCount();
logger.debug("Search results size {}", totalHitCount);

Manual Index Creation APIs using Spring data elastic search

Is there a way to create index manually using spring data elastic search and Java High Level Rest Client.
These are some of the api's that come to my mind which are specific to elastic index.
type is also taken as an argument because it is closely related with ES index.
createIndexWithCustomMappings(String indexName, String fieldMappings);
createTypeWithCustomMappings(String indexName, String type, String fieldMappings);
addAlias(String aliasName);
fetchAlias(String aliasName);
deleteIndex(String indexName);
getTypeSchema(String indexName, String type);
Using Spring Data Elasticsearch you will have an ElasticsearchOperations instance injected in your application.
#Autowired
ElasticsearchOperations operations;
You can use this to obtain a IndexOperations instance:
IndexOperations indexOperations = operations.indexOps(IndexCoordinates.of("indexname"));
IndexOperations has 4 different methods to create an index, the easiest being
indexOperations.create();
There are other methods to create the index with settings and/or mappings, check the Javadoc

Inject additional logic when elastic searches based on search query

I have a scenario where i need to extend search behavior and add some additional filter logic based on the document id . If the document can be visible to the user searching and then show in search result but have not found any.
Currently as part of search , search query is executed after applying all the filters. After the search results are fetched, we need to know if the resource can be shown to this user. Pretty much like ACL.
Now, if i apply these authorization/ audience type filters myself after getting results from elastic search , it creates a lot of problems like the aggregations count changes post filter. Also, the pagination of results gets impacted.
Is a there a way to implement such rules as hook provided by elastic search. That is if i can implement some logic implementing some interface and then call some web service returning a boolean and then adding the search result to the final collection based on that.
Some insight would be very useful.

How to make full text search with mongodb spring data?

Before asking this question, I have searched much about my problem. I need to make full text search from mongodb in spring framework. Up to now I just tried something with regex, but it does not cover my requirement. For example, I have a search string as 'increased world population' , and my search algorithm should return documents well-matched to search string or documents including at least one word from search string. I know Lucene does full text search, but I don't know how to implement it with my mongodb spring data and I dont know whether spring data already offer full text search. I need a tutorial which explain that.
what I have done up to now:
Criteria textCriteri = Criteria.where("title").regex(searchStr.trim().replaceAll(" +", " "), "i");
Query query = new Query(locationCriteria).addCriteria(textCriteri).limit(Consts.MONGO_QUERY_LIMIT);
List<MyObject> advs = mongoTemplate.find(query, MyObject.class);
You can create a 'text' index in mongodb and search through that, see http://docs.mongodb.org/manual/core/index-text/
Depending on your search queries, you probably want to use a more powerful search engine like ElasticSearch (as you mentioned Lucene).

Search for substring in a node name in JCR using CQ querybuilder

I am trying to do a search in CRXDE in CQ using the CQ qurybuilder tool to find all node names(in the tree structure) that contain the character '#' but am not successful. Being new to the Querybuilder tool, I am not aware of the exact conditions to be used to do the same.
Kindly help.
I tried the following query in the /bin/querybuilder.json tool-type=nt:file&path=/content/dam/marketinghub&property=nodename&property.value=#
I think the property=nodename part is wrong. What should I mention as property name when I have to search in the node names itself and not in any specific property of the node?
Almost there, but it is not the property that you need to search, it is the name of the node.
You have a nodename predicate that gets this job done for you.
It accepts a pattern that you would like to search for. So in your case, the query would be
type = nt:file
path = /content/dam/marketinghub
nodename = *#*
The json querybuilder url would be
/bin/querybuilder.json?nodename=*%23*&path=%2fcontent%2fdam%2fmarketinghub&type=nt%3afile
For further learning on query builder, refer this doc.

Resources