Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Hibernate Search query DSL构建模糊查询时如何处理同义词和停止词_Java_<img Src="//i.stack.imgur.com/RUiNP.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">elasticsearch_Lucene_Hibernate Search - Fatal编程技术网 elasticsearch,lucene,hibernate-search,Java,elasticsearch,Lucene,Hibernate Search" /> elasticsearch,lucene,hibernate-search,Java,elasticsearch,Lucene,Hibernate Search" />

Java 使用Hibernate Search query DSL构建模糊查询时如何处理同义词和停止词

Java 使用Hibernate Search query DSL构建模糊查询时如何处理同义词和停止词,java,elasticsearch,lucene,hibernate-search,Java,elasticsearch,Lucene,Hibernate Search,使用Hibernate搜索(5.8.2.Final)将DSL查询到Elasticsearch服务器 给定一个执行小写标准停止词的字段分析器,然后自定义同义词: company => co 最后,还有一个自定义的停止词: co 我们还为供应商名称编制了索引:Great spulding Company,在同义词和停止词之后的弹性搜索中,它归结为两个术语:Great和spulding 我试图构建我的查询,使每个术语“必须”匹配,模糊或精确,取决于术语长度 我得到了我想要的结果,除非其中一个

使用Hibernate搜索(5.8.2.Final)将DSL查询到Elasticsearch服务器

给定一个执行小写标准停止词的字段分析器,然后自定义同义词:

company => co
最后,还有一个自定义的停止词:

co
我们还为供应商名称编制了索引:
Great spulding Company
,在同义词和停止词之后的弹性搜索中,它归结为两个术语:
Great
spulding

我试图构建我的查询,使每个术语“必须”匹配,模糊或精确,取决于术语长度

我得到了我想要的结果,除非其中一个术语恰好是同义词或停止词,并且足够长,我的代码会给它增加模糊性,如
company~1
,在这种情况下,它不再被视为同义词或停止词,并且我的查询返回不匹配,由于“company”从未存储在b/c的第一个位置,因此它变为“co”,然后作为停止词删除

是时候写点代码了。这似乎有点老套,但我已经尝试了多种方法,使用
simpleQueryString
withAndAsDefaultOperator
并构建我自己的短语似乎能让我最接近我需要的结果(但我愿意接受建议)。我在做一些事情,比如:

// assume passed in search String of "Great Spaulding Company"
String vendorName = "Great Spaulding Company";  
List<String> vendorNameTerms = Arrays.asList(vendorName.split(" "));
List<String> qualifiedTerms = Lists.newArrayList();

vendorNameTerms.forEach(term -> {
    int editDistance = getEditDistance(term); // 1..5 = 0, 6..10 = 1, > 10 = 2 
    int prefixLength = getPrefixLength(term); //appears of no use with simpleQueryString

    String fuzzyMarker = editDistance > 0 ? "~" + editDistance : "";
    qualifiedTerms.add(String.format("%s%s", term, fuzzyMarker));
});

// join my terms back together with their optional fuzziness marker
String phrase = qualifiedTerms.stream().collect(Collectors.joining(" "));

bool.should(
        qb.simpleQueryString()
                .onField("vendorNames.vendorName")
                .withAndAsDefaultOperator()
                .matching(phrase)
                .createQuery()
);
//假设传入了“大斯波尔公司”的搜索字符串
String vendorName=“伟大的Spaulding公司”;
List vendorNameTerms=Arrays.asList(vendorName.split(“”);
List qualifiedTerms=Lists.newArrayList();
vendorNameTerms.forEach(期限->{
int editDistance=getEditDistance(term);/1..5=0,6..10=1,>10=2
int prefixLength=getPrefixLength(term);//似乎对simpleQueryString没有用处
字符串fuzzyMarker=editDistance>0?~“+editDistance:”;
qualifiedTerms.add(String.format(“%s%s”,term,fuzzyMarker));
});
//将我的术语与它们可选的模糊标记结合起来
字符串短语=qualifiedTerms.stream().collect(collector.joining(“”);
应该(
qb.simpleQueryString()
.onField(“vendorNames.vendorName”)
.WithAndAndDefaultOperator()
.匹配(短语)
.createQuery()
);
正如我上面所说的,我发现只要我不对可能的同义词或停止词添加任何模糊性,查询就会找到匹配项。因此,这些短语返回一个匹配项:
“大斯普林1号”
“大斯普林1号公司”
“斯普林1号公司”

但由于我的代码不知道什么术语是同义词或停止词,它会盲目地查看术语长度并说,“哦,'公司'大于5个字符,我会将其模糊化,它构建了这些不返回匹配项的短语:
“大公司1号”
“大公司1号”

  • 为什么Elasticsearch没有将
    公司~1
    作为同义词处理
  • 关于如何使用simpleQueryString或 另一个DSL查询
  • 每个人如何处理可能包含停止词的文本的模糊搜索
  • [编辑]我的分析器通常会删除的标点符号也会出现同样的问题。我的查询b/c中的模糊搜索字符串中不能包含任何标点符号ES analyzer似乎没有将其视为非模糊,并且我没有得到匹配结果

    基于上述搜索字符串的示例:
    Great spauding Company.,
    在我的代码中生成短语
    Great spauding~1 Company.,~1
    ,ES不会删除标点符号或识别同义词
    Company

    我将尝试调用ES_analyze restapi,让它告诉我应该在查询中包含哪些标记,尽管这会增加我构建的每个查询的开销。类似于
    http://localhost:9200/myEntity/_analyze?analyzer=vendorNameAnalyzer&text=Great Spaulding Company.,
    生产3种代币:
    great
    Spaulding
    Company

    为什么Elasticsearch不是将Company~1作为同义词处理

    我猜这是因为模糊查询是,这意味着它们根据精确的术语而不是分析的文本进行操作。如果一经分析,您的术语解析为多个标记,我认为为模糊查询定义可接受的行为并不容易

    还有更详细的解释(我相信它仍然适用于ElasticSearch5.6中使用的Lucene版本)

    您知道如何使用simpleQueryString或其他DSL查询来实现这一点吗? 每个人如何处理可能包含停止词的文本的模糊搜索

    您可以尝试反转同义词:使用
    co=>company
    而不是
    company=>co
    ,这样即使未分析“compayn”,诸如
    compayn~1
    之类的查询也会匹配。但这当然不是一个令人满意的解决方案,因为其他需要分析的示例仍然不起作用,例如
    公司~1

    以下是替代方案

    解决方案1:具有模糊性的“匹配”查询 描述执行模糊搜索的方法,并特别说明几种类型的模糊查询之间的差异

    不幸的是,“简单查询字符串”查询中的模糊查询似乎被转换为不执行分析的查询类型

    但是,根据您的要求,这可能就足够了。为了访问Elasticsearch提供的所有设置,您必须返回到本机查询构建:

        QueryDescriptor query = ElasticsearchQueries.fromJson(
                "{ 'query': {"
                    + "'match' : {"
                        + "'vendorNames.vendorName': {"
                            // Not that using a proper JSON framework would be better here, to avoid problems with quotes in the terms
                            + "'query': '" + userProvidedTerms + "',"
                            + "'operator': 'and',"
                            + "'fuzziness': 'AUTO'"
                        + "}"
                    + "}"
                + " } }"
        );
        List<?> result = session.createFullTextQuery( query ).list();
    
    QueryDescriptor query=elasticsearchquerys.fromJson(
    “{‘查询’:{”
    +“'match':{”
    +“'vendorNames.vendorName':{”
    //并不是说在这里使用合适的JSON框架会更好,以避免术语中引用的问题
    +“'query':'”+userProvidedTerms+“,”
    +“‘运算符’:‘和’,”
    +“‘模糊’:‘自动’”