【问题标题】:hibernate query not searching beyond 2 characters for some strings and not working on multi word search休眠查询不搜索超过 2 个字符的某些字符串并且不进行多字搜索
【发布时间】:2018-08-29 12:31:13
【问题描述】:

我正在尝试通过休眠搜索实现全文搜索功能。我们需要搜索姓名、地址等。 用户可以搜索名称“John”、“Johm Murphy”、“Mark”、“Mark L Thomas”,也可以搜索“20601 Blvd”、“一楼”等地址。

虽然当前的逻辑适用于少数几个单词,例如“John”是可搜索的,但不是“Mark”,但如果我说“Ma”,那么我有结果,但如果我写 Mar 或 Mark,它不会给出任何记录。我还可以搜索城市为哥伦比亚。

多词搜索也不起作用。

当我不使用任何分析器(如在当前下面的代码中)时,上述语句有效,如果我使用 edgengram、文本、标准分析器,那么我有不同的输出。但是没有一个分析仪工作。 以下是完整代码:

我试图从中检索数据的索引结构:

  > {
>         "_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"
>           }
>         }
>       }

同一索引的索引定义:

    {
>   "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"
>       }
>     }
>   }
> }

包含字段的 java 对象:

    @Field(name = "longname", index = Index.YES, store = Store.YES,
            analyze = Analyze.YES)
    private String longname = "";

@Field(name = "firstname", index = Index.YES, store = Store.YES,
    analyze = Analyze.YES)
    private String firstname = "";

此外,目前我正在使用通配符上下文查询:

    public synchronized void searchClienData() {
   String lowerCasedSearchTerm = this.data.getSearchText().toLowerCase();

    SearchFactory searchFactory = fullTextSession.getSearchFactory();
    QueryBuilder buildQuery = searchFactory.buildQueryBuilder().forEntity(Basclt0300TO.class).get();

    String[] projections = {"basclt0100to.longname", "basclt0100to.cltseqnum", "addrln1", "addrln2", 
            "city","state","zipcode", "country","basclt0900to.email1" };

     Query query = queryBuilder.keyword()
    .onField("basclt0100to.longname").andField("addrln1").andField("addrln2")
    .andField("city").andField("state").andField("country").matching(lowerCasedSearchTerm)
    .createQuery();

    FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, 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() {
        private static final long serialVersionUID = 1L;
        @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;

}

【问题讨论】:

    标签: elasticsearch lucene hibernate-search


    【解决方案1】:

    首先,您需要将分析器定义实际分配给您的字段。仅仅定义分析器是不够的。

    @Field(name = "longname", index = Index.YES, store = Store.YES,
            analyze = Analyze.YES, analyzer = @Analyzer(definition = "theNameOfSomeAnalyzerDefinition"))
    private String longname = "";
    
    @Field(name = "firstname", index = Index.YES, store = Store.YES,
        analyze = Analyze.YES, analyzer = @Analyzer(definition = "theNameOfSomeAnalyzerDefinition"))
    private String firstname = "";
    

    然后,您需要选择一个策略并坚持下去:

    • 要么使用通配符查询,它易于使用且不需要 EdgeNGram 令牌过滤器,但往往会导致problems due to the query terms not being analyzed
    • 或者您将 EdgeNGram 令牌过滤器应用于您的字段,并在查询时:
      • 使用关键字查询不带通配符选项
      • override the analyzers 使用不同的,它们应该与分配给您的字段的分析器具有相同的定义,但它们不应使用 EdgeNGram 令牌过滤器。

    但不要混合使用这两种方法。绝不。它只是行不通。

    【讨论】:

    • 如果我理解正确的话。 1. 我需要在字段的代码中使用我已经拥有的 EdgeNGram 过滤器。 2. 我需要使用简单的关键字查询。但他们会处理“John L Murphy”和“Neha Micheal”等多个词吗?
    • 再查询一次。如何覆盖多个字段。因为我需要搜索多个字段。
    • 1.是的。 2. 是的,是的,如果您的分析器执行标记化(使用“WhitespaceTokenizerFactory”而不是“KeywordTokenizerFactory”),它们将使用多个单词。我知道,“keyword()”对于 DSL 方法来说是个坏名字。 3. 正如我所说,my_analyzer_without_ngrams 应该完全定义为应用于字段的分析器,但没有EdgeNGram 标记过滤器。
    • 通过多次调用overrideForField()方法覆盖多个字段。
    • 我已按照建议实施,但现在我的简单关键字查询没有得到任何结果。 Query query = queryBuilder.keyword() .onFields("basclt0100to.longname", "basclt0100to.firstname", "addrln1", "addrln2" ,"city","state","zipcode", "country", "basclt0900to.email1") .matching(lowerCasedSearchTerm) .createQuery();我在这里做错了什么。请指教。
    猜你喜欢
    • 1970-01-01
    • 2020-05-01
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多