当前位置: 首页 > 知识库问答 >
问题:

ElasticSearch QueryBuilder must_not子句奇怪行为

黎征
2023-03-14

根据文献记载

must_not子句(query)不能出现在匹配的文档中。

我有如下查询:

// searching for URI which contains smart and doesn't contain vip.vs.csin.cz
BoolQueryBuilder builder = QueryBuilders.boolQuery();
builder.must(QueryBuilders.termQuery(URI, "smart")));
builder.mustNot(QueryBuilders.termQuery(URI, "vip.vs.csin.cz")));

在我的elasticsearch存储库中有两个URI

1)

elasticsearchTemplate.getClient().search(searchRequest);
uri: "smart" NOT uri: "vip.vs.csin.cz"

编辑这里是我的映射

@Document(indexName = "audit-2018", type = "audit")
public class Trace {

    @Id
    private String id;
    @Field(type = FieldType.Text)
    private String uri;

    // more columns, getter & setters
}

共有1个答案

笪昌翰
2023-03-14

您提供的Java代码显示了一个使用mustmust_not子句的bool查询,其中您正在执行一个术语查询。术语查询的问题在于,它们受制于字段上的分析器,text(这是URI字段的数据类型,在这里阅读更多信息)字段的标准分析器将删除所有标点符号(换句话说,单词中的点)并将单词拆分。vip.vs.csin.cz变为vip vs csin cztext字段类型应该只为全文搜索保留,在这种情况下,我会选择keyword字段类型(在这里阅读更多内容)。Kibana查询按预期工作的原因是,它实际上不是在执行术语查询,而是包含lucene查询的query_string查询:URI:"smart“而不是URI:"vip.vs.csin.cz”

因此,您有几个选项来解决您的问题。您可以将术语查询更改为match_prace查询,这将允许您保留标记化术语的顺序,并可能获得正确的结果。另一种选择是在Java代码中执行query_string查询而不是术语查询,因为您已经确定这确实会给出正确的结果。

但是,我建议的解决方案是使用URI字段类型keyword重新索引,因为这种字段类型不会导致将字段值标记为多个术语。您可以在这里阅读有关关键字字段类型的默认分析器和标记器的更多信息。这将为您将来省去麻烦,因为您知道您的查询与您的字段值完全“按原样”匹配。

 类似资料:
  • 这个程序打印00,但是如果我注释掉a.store和b.store,而取消注释a.fetch_add和b.fetch_add,这做了完全相同的事情,即都设置了a=1,b=1的值,我永远不会得到00。 是我错过了什么,还是“00”按标准永远不会出现? 下面打印00。 下图从不打印00 再看看这个,多线程原子a b打印00 for memory_order_refield

  • 我有以下代码来解析一个JSON文件: 要处理以下JSON文件: 如果我执行此代码,我将收到以下错误: 所以我开始一步一步地调试应用程序,看看part processing()中的哪个代码部分抛出了这个异常。令人惊讶的是,那里的所有代码都正常执行:没有抛出异常,也没有返回结果I except。 更让我惊讶的是,当我稍微改变第一种方法的代码时,它可以在不产生异常的情况下工作。 我不知道println方

  • 问题内容: 我在GregorianCalendar类中遇到一个奇怪的行为,我想知道我是否真的做得不好。 仅当初始化日期的月份的实际Maximum大于我将日历设置为的月份时,才追加此值。 这是示例代码: 我知道问题是由于日历初始化日期是31天(可能是5月),与设置为2月(28天)的月份混淆了。修复很容易(只需在设置年和月之前将day_of_month设置为1),但是我想知道这确实是想要的行为。有什么

  • 问题内容: 我正在为一个问题而苦苦挣扎,我不明白为什么它不起作用。如何通过将变量传递并转换为? 为什么在顶部代码段中不起作用,但在行下方的底部代码段中起作用? 唯一的区别似乎是添加了一个额外的变量,该变量也被键入为? 问题答案: 该是一种原始类型,同时是一个普通的Java类。您不能在原始类型上调用方法。但是该方法在上可用,如javadoc中所示 有关这些原始类型的更多信息,请参见此处

  • 问题内容: 为什么的到哪里去了? 问题答案: 删除任何字符,并从字符串的开头和结尾。

  • 问题内容: 我认为这是一个正常程序,但这是我得到的输出: 有人可以向我解释一下吗? 问题答案: 这是有据可查的PHP行为,请参阅php.net的foreach页面上的警告。 警告 即使在 foreach 循环之后,仍保留 $ value的 引用和最后一个数组元素。建议通过unset()销毁它。 __ 编辑 尝试逐步了解此处实际发生的情况