ES中关于must和should组合使用过程中较为复杂的问题
问题描述:今天在做项目时,遇到一个问题,查询某个人在es中的文档(邮件),docId是唯一的,所以查询的结果中docId必须包含该人的邮箱地址,然后邮件主题subject或者邮件内容content中只要其中之一包含所要索引的内容就可以。然后,先使用了下面的查询:Page<MailDocsE> findDistinctByDocIdContainsAndSubjectOrContentA
问题描述:今天在做项目时,遇到一个问题,查询某个人在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中的两个条件至少满足一个才可以。
更多推荐
所有评论(0)