java - Elasticsearch Must_not 不使用过滤器子句

标签 java elasticsearch elasticsearch-java-api

我正在从事医疗项目,我有多个问题及其附带的主题。问题是以下代码工作正常,但它没有考虑“must_not”过滤器,而使用“must”子句则工作正常。帮我解决这个问题。

GET stopdata/_search
{
  "query": {
    "function_score": {
      "query": {
        "filtered": {
          "query": {
            "match": {
              "question": "Hello Dr. Iam suffering from fever with cough nd cold since 3 days"
            }
          }
        }
      },
      "filter": {
        "bool": {
          "must": [
            {
              "terms": {
                "topics": [
                  "fever",
                  "cough"
                ]
              }
            }
          ],
          "must_not": [
            {
              "terms": {
                "topics": [
                  "children",
                  "child",
                  "childrens health"
                ]
              }
            }
          ]
        }
      },
      "random_score": {}
    }
  },
  "highlight": {
    "fields": {
      "keyword": {}
    }
  }
}

此外,我需要将代码转换为 Java,我正在尝试,但仍坚持使用以下代码。

Set<String> mustNot = new HashSet<String>();
mustNot.add("child");
mustNot.add("children");
mustNot.add("childrens health");

Set<String> must = new HashSet<String>();
must.add("fever");
must.add("cough");

FunctionScoreQueryBuilder fsqb = new FunctionScoreQueryBuilder(QueryBuilders.matchQuery("question", "Hello Dr. Iam suffering from fever with cough nd cold since 3 days"));
fsqb.add(ScoreFunctionBuilders.randomFunction((new Date()).getTime()));

BoolQueryBuilder bqb = boolQuery()
        .mustNot(termsQuery("topics", mustNot));

SearchResponse response1 = client.prepareSearch("stopdata")
        .setQuery(fsqb)
        .execute()
        .actionGet();

System.out.println(response1.getHits().getTotalHits());

“stopdata”索引的映射如下

{
   "stopdata": {
      "mappings": {
         "questions": {
            "properties": {
               "answers": {
                  "type": "string"
               },
               "id": {
                  "type": "long"
               },
               "question": {
                  "type": "string",
                  "analyzer": "my_english"
               },
               "relevantQuestions": {
                  "type": "long"
               },
               "topics": {
                  "type": "string"
               }
            }
         }
      }
   }
}

为上述索引添加示例数据

"question": "My son of age 8 months is suffering from cough and cold and fever. What treatment I have to follow?"
"topics": [
  "Cough",
  "Fever",
  "Hydration",
  "Nutrition",
  "Tens",
  "Childrens health"
]

"question": "Hi.My daughter, 4 years old , has on and of fever  with severe coughing and colds for 3 days now.She vomited as well last night.Do you think it's viral?"
"topics": [
  "Vomiting",
  "Flu",
  "Cough",
  "Fever",
  "Pneumonia",
  "Meningitis",
  "Tamiflu",
  "Incision",
  "Childrens health",
  "Oseltamivir"
]

"question": "If you have a fever of 101 with chills and sweats for 2 day with a slight cough, should you go to the drs or let is wear off?"
"topics": [
  "Cough",
  "Fever"
]

最佳答案

我看到的是整个filter部分放错了地方,它应该进入filtered查询内部,因为没有filter function_score 元素的根元素(请参阅 official docs )。因此,您的查询首先应该如下所示 + 您应该使用 POST 而不是 GET,因为您要发送有效负载:

POST stopdata/_search
{
  "query": {
    "function_score": {
      "query": {
        "filtered": {
          "query": {
            "match": {
              "question": "Hello Dr. Iam suffering from fever with cough nd cold since 3 days"
            }
          },
          "filter": {
            "bool": {
              "must": [
                {
                  "terms": {
                    "topics": [
                      "fever",
                      "cough"
                    ]
                  }
                }
              ],
              "must_not": [
                {
                  "terms": {
                    "topics": [
                      "children",
                      "child",
                      "childrens health"
                    ]
                  }
                }
              ]
            }
          }
        }
      },
      "random_score": {}
    }
  },
  "highlight": {
    "fields": {
      "keyword": {}
    }
  }
}

现在用 Java 编写所有这些,如下所示:

Set<String> mustNot = new HashSet<String>();
mustNot.add("child");
mustNot.add("children");
mustNot.add("childrens health");

Set<String> must = new HashSet<String>();
must.add("fever");
must.add("cough");

MatchQueryBuilder query = QueryBuilders.matchQuery("question", "Hello Dr. Iam suffering from fever with cough nd cold since 3 days");

BoolFilterBuilder filter = FilterBuilders.boolFilter()
    .must(FilterBuilders.termsFilter("topics", must))
    .mustNot(FilterBuilders.termsFilter("topics", mustNot));

FilteredQueryBuilder fqb = QueryBuilders.filteredQuery(query, filter);

FunctionScoreQueryBuilder fsqb = QueryBuilders.functionScoreQuery(fqb);
fsqb.add(ScoreFunctionBuilders.randomFunction((new Date()).getTime()));

SearchResponse response1 = client.prepareSearch("stopdata")
        .setQuery(fsqb)
        .execute()
        .actionGet();

System.out.println(response1.getHits().getTotalHits());

更新

must_notchildrens health 不匹配的原因是分析了 topics 字段,从而分析了 Childrens health 被标记化并分析为两个标记 childrenshealth,从而尝试对 childrens health 进行 terms 匹配> 不会产生任何结果。也许,分成两个术语会有所帮助:

              "must_not": [
                {
                  "terms": {
                    "topics": [
                      "children",
                      "child",
                      "childrens", 
                      "health"
                    ]
                  }
                }
              ]

关于java - Elasticsearch Must_not 不使用过滤器子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33913651/

相关文章:

elasticsearch - 如何在ES 6.4中使用新的Java Api重新编制索引?

elasticsearch - 如何使用org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder映射Java中的多字段

java - 无可用节点异常 Elasticsearch 5.0.2

java - 编译错误 - 在 IntelliJ IDEA 中复制类

java - 错误的类型推断

c# - 具有不同类型的Elasticsearch map 属性

sorting - ElasticSearch-按子聚合排序

java - HADOOP - 如何在 map 中动态加载类

java - 为什么我不能从 Java 中的专用枚举值访问静态最终成员

elasticsearch - 如何分割用户