问题描述:今天在做项目时,遇到一个问题,查询某个人在es中的文档(邮件),docId是唯一的,所以查询的结果中docId必须包含该人的邮箱地址,然后邮件主题subject或者邮件内容content中只要其中之一包含所要索引的内容就可以。然后,先使用了下面的查询:

Page<MailDocsE> findDistinctByDocIdContainsAndSubjectOrContentAndFoundTimeBetweenOrderByFoundTimeDesc(String docId, String subject, String content, Long start, Long end, Pageable pageable);

以上在原问题上添加了查询时间段和分页信息(不影响)。结果显示查询不出来,具体测试发现:Subject和Content哪个写在前面哪个起作用,而写在Or后面的则不起作用。找到问题后,想起来了用@query注解解决该问题。首先写了以下方法:

//查询主题+内容+时间段
@Query(value = "{\"bool\":{\"must\": [\n" +
        "  {\"query_string\": {\n" +
        "    \"query\": \"*?0*\",\"fields\": [\"docId\"]}}],\"should\": [\n" +
        "      {\"query_string\": {\n" +
        "        \"fields\": [\"subject\"],\n" +
        "        \"query\": \"?1\"\n" +
        "      }},{\"query_string\": {\n" +
        "      \"fields\": [\"content\"],\n" +
        "      \"query\": \"?2\"}\n" +
        "    }\n" +
        "],\"filter\": { \n" +
        "\t\t\"range\" : {\n" +
        "\t\t\t\"foundTime\" : {\n" +
        "\t\t\t\t\"gt\" : \"?3\",\n" +
        "\t\t\t\t\"lt\" : \"?4\"\n" +
        "\t\t\t}\n" +
        "\t\t}\n" +
        "    }}}")

Page<MailDocsE> findDistinctByDocIdContainsAndSubjectOrContentAndFoundTimeBetweenOrderByFoundTimeDesc(String docId, String subject, String content, Long start, Long end, Pageable pageable);

总结上面方法:must和should属于并列的,查询结果中出现了那种should不起作用的情况,比如:出现了subject和content中都不包含索引内容的数据,说明失败了,should没起作用。网上查询,发现了问题,有人说should必须包含在must查询体中才可以,不能是并列的。然后修改如下:

//查询主题+内容+时间段

@Query(value = "{\"bool\": { \"must\": [\n" +
        " {\"query_string\": {\n" +
        "\"query\":  \"*?0*\",\n" +
        " \"fields\": [\"docId\"]\n" +
        "}},\n" +
        "{\n" +
        " \"bool\": {\n" +
        "\"should\": [\n" +
        " {\"query_string\": {\n" +
        "\"query\": \"?1\",\n" +
        "\"fields\": [\"subject\"]\n" +
        "}},\n" +
        "{\n" +
        "\"query_string\": {\n" +
        "\"query\": \"?2\",\n" +
        "\"fields\": [\"content\"]\n" +
        "}}\n" +
        "]\n" +
        "}}],\"filter\": { \n" +
        "\t\t\"range\" : {\n" +
        "\t\t\t\"foundTime\" : {\n" +
        "\t\t\t\t\"gt\" : \"?3\",\n" +
        "\t\t\t\t\"lt\" : \"?4\"\n" +
        "\t\t\t}\n" +
        "\t\t}\n" +
        "    }\n" +
        "}}")

Page<MailDocsE> findDistinctByDocIdContainsAndSubjectOrContentAndFoundTimeBetweenOrderByFoundTimeDesc(String docId, String subject, String content, Long start, Long end, Pageable pageable);

经测试:终于work了!!!

简单版的例子(kibana中):

GET mail_e/_search
{
 "query": {"bool": { "must": [
 {"query_string": {
"query":  "*huxinran@maoyt.com*",
 "fields": ["docId"]
}},
{
 "bool": {
"should": [
 {"query_string": {
"query": "差旅费",
"fields": ["subject"]
}},
{
"query_string": {
"query": "差旅费",
"fields": ["content"]
}}
]
}}]
}}}

上面的这个查询,must的条件必须满足,should中的两个条件至少满足一个才可以。

 

 

 

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐