Мы используем поисковую форму hibernate 5.9.2 и хотели бы получить точные результаты поиска, такие как:
Если пользователь начинает с
John -> all data with John should display
John Murphy -> all data with John murphy should display
John murphy Columbia -> Only data with John murphy Columbia should display
John murphy Columbia SC -> Only data with John murphy Columbia should display
John murphy Columbia SC 29201 -> Only data with John murphy Columbia SC 29201
29201 -> Only data with 29201 as zipcode should be displayed.
and so on...
В основном мы пытаемся выполнить поиск по точным записям из нескольких полей индекса.
У нас есть объект, содержащий эти данные в таких полях, как Имя, Адрес1, Адрес2, Город, Почтовый индекс, Штат.
Мы пробовали bool()
(с must / must) запросами, но поскольку мы не уверены, какие данные пользователь будет вводить первыми, это может быть почтовый индекс, штат, город в любом месте текстового поиска.
Пожалуйста, поделитесь своими знаниями / логикой в отношении анализаторов / стратегий, которые мы можем использовать для достижения этой цели с помощью hibernate search / lucene.
Ниже приведена структура индекса:
> {
> "_index" : "client_master_index_0300",
> "_type" : "com.csc.pt.svc.data.to.Basclt0300TO",
> "_id" : "518,1",
> "_score" : 4.0615783,
> "_source" : {
> "id" : "518,1",
> "cltseqnum" : 518,
> "addrseqnum" : "1",
> "addrln1" : "Dba",
> "addrln2" : "Betsy Evans",
> "city" : "SDA",
> "state" : "SC",
> "zipcode" : "89756-4531",
> "country" : "USA",
> "basclt0100to" : {
> "cltseqnum" : 518,
> "clientname" : "Betsy Evans",
> "longname" : "Betsy Evans",
> "id" : "518"
> },
> "basclt0900to" : {
> "cltseqnum" : 518,
> "id" : "518"
> }
> }
> }
Ниже ввод
Акаш Агравал 29021
ответ содержит все записи, соответствующие akash, agrwal, 29,2, 1, 01 и т. Д ...
То, чего мы пытаемся достичь, - это точный результат поиска, в отношении указанного выше поискового ввода результаты должны содержать только данные с Akash Agrawal 29201, а не другие данные.
Мы в основном ищем имя basclt0100to.longname, addrln1, addrln2, город, штат, почтовый индекс, страну.
Определение индекса ниже
> {
> "client_master_index_0300" : {
> "aliases" : { },
> "mappings" : {
> "com.csc.pt.svc.data.to.Basclt0300TO" : {
> "dynamic" : "strict",
> "properties" : {
> "addrln1" : {
> "type" : "text",
> "store" : true
> },
> "addrln2" : {
> "type" : "text",
> "store" : true
> },
> "addrln3" : {
> "type" : "text",
> "store" : true
> },
> "addrseqnum" : {
> "type" : "text",
> "store" : true
> },
> "basclt0100to" : {
> "properties" : {
> "clientname" : {
> "type" : "text",
> "store" : true
> },
> "cltseqnum" : {
> "type" : "long",
> "store" : true
> },
> "firstname" : {
> "type" : "text",
> "store" : true
> },
> "id" : {
> "type" : "keyword",
> "store" : true,
> "norms" : true
> },
> "longname" : {
> "type" : "text",
> "store" : true
> },
> "midname" : {
> "type" : "text",
> "store" : true
> }
> }
> },
> "basclt0900to" : {
> "properties" : {
> "cltseqnum" : {
> "type" : "long",
> "store" : true
> },
> "email1" : {
> "type" : "text",
> "store" : true
> },
> "id" : {
> "type" : "keyword",
> "store" : true,
> "norms" : true
> }
> }
> },
> "city" : {
> "type" : "text",
> "store" : true
> },
> "cltseqnum" : {
> "type" : "long",
> "store" : true
> },
> "country" : {
> "type" : "text",
> "store" : true
> },
> "id" : {
> "type" : "keyword",
> "store" : true
> },
> "state" : {
> "type" : "text",
> "store" : true
> },
> "zipcode" : {
> "type" : "text",
> "store" : true
> }
> }
> }
> },
> "settings" : {
> "index" : {
> "creation_date" : "1535607176216",
> "number_of_shards" : "5",
> "number_of_replicas" : "1",
> "uuid" : "x4R71LNCTBSyO9Taf8siOw",
> "version" : {
> "created" : "6030299"
> },
> "provided_name" : "client_master_index_0300"
> }
> }
> }
> }
До сих пор я пытался использовать edgengraanalyzer, стандартный анализатор запросов lucene. Я пробовал с помощью запроса Bool (), запроса по ключевому слову, фразы, пробовал все, что доступно в документации.
Но я уверен, что мне не хватает стратегии / логики, которую мы должны использовать.
Ниже приведен текущий запрос, который я использую и который дает результаты прикрепленного снимка
Query finalQuery = queryBuilder.simpleQueryString()
.onFields("basclt0100to.longname", "addrln1", "addrln2"
,"city","state","zipcode", "country")
.withAndAsDefaultOperator()
.matching(lowerCasedSearchTerm)
.createQuery();
FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(finalQuery, Basclt0300TO.class);
fullTextQuery.setMaxResults(this.data.getPageSize()).setFirstResult(this.data.getPageSize());
List<String> projectedFields = new ArrayList<String>();
for (String fieldName : projections)
projectedFields.add(fieldName);
@SuppressWarnings("unchecked")
List<Cltj001ElasticSearchResponseTO> results = fullTextQuery.
setProjection(projectedFields.toArray(new String[projectedFields.size()]))
.setResultTransformer( new BasicTransformerAdapter() {
@Override
public Cltj001ElasticSearchResponseTO transformTuple(Object[] tuple, String[] aliases) {
return new Cltj001ElasticSearchResponseTO((String) tuple[0], (long) tuple[1],
(String) tuple[2], (String) tuple[3], (String) tuple[4],
(String) tuple[5],(String) tuple[6], (String) tuple[7], (String) tuple[8]);
}
})
.getResultList();
resultsClt0300MasterIndexList = results;
искал: akash 29201 & искал: akash 1 main
Здесь вы видите, что у нас есть все данные, содержащие akash, sh, 29, 292, 29201.
Ожидаемые результаты:
Акаш Агравал - 29201
Akash Agrawal - 1 главная улица, SC, 29201
В основном только точные данные, содержащие / соответствующие входной строке.
Использованные анализаторы:
Указатель времени
@AnalyzerDef(name = "autocompleteEdgeAnalyzer",
//Split input into tokens according to tokenizer
tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = StopFilterFactory.class),
@TokenFilterDef(
factory = EdgeNGramFilterFactory.class, // Generate prefix tokens
params = {
@Parameter(name = "minGramSize", value = "3"),
@Parameter(name = "maxGramSize", value = "3")
}
)
})
Переопределение времени запроса с помощью:
@AnalyzerDef(name = "withoutEdgeAnalyzerFactory",
// Split input into tokens according to tokenizer
tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = ASCIIFoldingFilterFactory.class),
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
}
/*filters = {
// Normalize token text to lowercase, as the user is unlikely to
// care about casing when searching for matches
@TokenFilterDef(factory = PatternReplaceFilterFactory.class, params = {
@Parameter(name = "pattern", value = "([^a-zA-Z0-9\\.])"),
@Parameter(name = "replacement", value = " "),
@Parameter(name = "replace", value = "all") }),
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = StopFilterFactory.class) }*/)
Надеюсь, эти данные помогут.