我正在使用Elasticsearch 5.2
。我正在针对只有一个文档的索引执行以下查询
查询:
GET test/val/_validate/query?pretty&explain=true
{
"query": {
"bool": {
"should": {
"multi_match": {
"query": "alkis stackoverflow",
"fields": [
"name",
"job"
],
"type": "most_fields",
"operator": "AND"
}
}
}
}
}
文件:
PUT test/val/1
{
"name": "alkis stackoverflow",
"job": "developer"
}
查询的解释是
+(((+job:alkis +job:stackoverflow) (+name:alkis +name:stackoverflow))) #(#_type:val)
我读到这个:
现场工作必须有alkis
和stackoverflow
和
字段名称必须为alkis
和stackoverflow
但我的文件并非如此。这两个字段之间的AND
实际上是OR
(从我得到的结果看来)
当我将类型更改为best_fields
时,我得到了
+(((+job:alkis +job:stackoverflow) | (+name:alkis +name:stackoverflow))) #(#_type:val)
这是正确的解释。
验证API是否有错误?我误解了什么吗?这两种类型之间的唯一差异不是得分吗?
答案 0 :(得分:1)
由于您使用明确的most_fields
运算符选择了AND
类型,the reasoning是每个字段将生成一个匹配查询,并且所有字词必须存在于这是一个匹配的文档的单个字段,这是您的情况,即alkis
字段中存在stackoverflow
和name
两个术语,因此文档匹配的原因。< / p>
所以在解释相应的Lucene查询时,即
+(((+job:alkis +job:stackoverflow) (+name:alkis +name:stackoverflow)))
之间未指定特定运算符时
因此,您需要将其视为:字段job
必须同时包含alkis
和stackoverflow
或字段name
必须同时包含alkis
1}}和stackoverflow
。
您应用的AND运算符仅涉及查询中的所有术语,但就单个字段而言,它不是所有字段之间的AND。换句话说,您的查询将在match
子句中作为两个bool/should
查询(每个字段一个)执行,如下所示:
{
"query": {
"bool": {
"should": [
{ "match": { "job": "alkis stackoverflow" }},
{ "match": { "name": "alkis stackoverflow" }}
]
}
}
}
总之,most_fields
类型在查询包含以不同方式分析的相同文本的多个字段时最有用。 这不是您的情况,您可能最好使用cross_fields
或best_fields
,具体取决于您的使用案例,但肯定不是most_fields
。
<强>更新强>
使用best_fields
类型时,ES会生成dis_max
query而不是bool/should
,|
(不是OR !!)符号会分隔所有子dis_max
查询中的查询。