组合字段

编辑

combined_fields 查询支持搜索多个文本字段,就好像它们的内容已被索引到一个组合字段中。该查询采用以词为中心的输入字符串视图:首先它将查询字符串分析为单个词,然后在任何字段中查找每个词。当匹配可能跨越多个文本字段时,此查询特别有用,例如文章的 titleabstractbody

resp = client.search(
    query={
        "combined_fields": {
            "query": "database systems",
            "fields": [
                "title",
                "abstract",
                "body"
            ],
            "operator": "and"
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      combined_fields: {
        query: 'database systems',
        fields: [
          'title',
          'abstract',
          'body'
        ],
        operator: 'and'
      }
    }
  }
)
puts response
const response = await client.search({
  query: {
    combined_fields: {
      query: "database systems",
      fields: ["title", "abstract", "body"],
      operator: "and",
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "combined_fields" : {
      "query":      "database systems",
      "fields":     [ "title", "abstract", "body"],
      "operator":   "and"
    }
  }
}

combined_fields 查询基于 The Probabilistic Relevance Framework: BM25 and Beyond 中描述的简单 BM25F 公式,采用一种有原则的评分方法。在对匹配项进行评分时,该查询会组合字段之间的词和集合统计信息,以便像指定的字段已索引到单个组合字段中一样对每个匹配项进行评分。此评分是尽力而为的尝试;combined_fields 会进行一些近似,并且评分不会完全遵循 BM25F 模型。

字段数量限制

默认情况下,查询可以包含的子句数量有限制。此限制由 indices.query.bool.max_clause_count 设置定义,该设置默认为 4096。对于组合字段查询,子句数量的计算方式为字段数量乘以词的数量。

每个字段的提升

编辑

字段提升根据组合字段模型进行解释。例如,如果 title 字段的提升值为 2,则评分的计算方式为好像标题中的每个词在合成组合字段中出现了两次。

resp = client.search(
    query={
        "combined_fields": {
            "query": "distributed consensus",
            "fields": [
                "title^2",
                "body"
            ]
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      combined_fields: {
        query: 'distributed consensus',
        fields: [
          'title^2',
          'body'
        ]
      }
    }
  }
)
puts response
const response = await client.search({
  query: {
    combined_fields: {
      query: "distributed consensus",
      fields: ["title^2", "body"],
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "combined_fields" : {
      "query" : "distributed consensus",
      "fields" : [ "title^2", "body" ] 
    }
  }
}

可以使用插入符号 (^) 表示法提升各个字段。

combined_fields 查询要求字段提升值大于或等于 1.0。字段提升值允许是小数。

combined_fields 的顶级参数

编辑
fields
(必需,字符串数组)要搜索的字段列表。允许使用字段通配符模式。仅支持 text 字段,并且它们都必须具有相同的搜索 analyzer
query

(必需,字符串)要在提供的 <fields> 中搜索的文本。

combined_fields 查询在执行搜索之前会分析提供的文本。

auto_generate_synonyms_phrase_query

(可选,布尔值)如果为 true,则会自动为多词同义词创建匹配短语查询。默认为 true

有关示例,请参阅将同义词与匹配查询结合使用

operator

(可选,字符串)用于解释 query 值中使用的文本的布尔逻辑。有效值为:

or(默认)
例如,query 值为 database systems 将解释为 database OR systems
and
例如,query 值为 database systems 将解释为 database AND systems
minimum_should_match

(可选,字符串)返回文档必须匹配的最小子句数量。有关有效值和更多信息,请参阅 minimum_should_match 参数

zero_terms_query

(可选,字符串)指示如果 analyzer 删除所有标记(例如,在使用 stop 过滤器时),是否不返回任何文档。有效值为:

none(默认)
如果 analyzer 删除所有标记,则不返回任何文档。
all
返回所有文档,类似于 match_all 查询。

有关示例,请参阅 零词查询

multi_match 查询的比较

编辑

combined_fields 查询提供了一种在多个 text 字段之间进行匹配和评分的有原则的方法。为了支持这一点,它要求所有字段具有相同的搜索 analyzer

如果您想要一个处理不同类型字段(如关键字或数字)的单个查询,则multi_match 查询可能更适合。它同时支持文本和非文本字段,并且接受不共享同一分析器的文本字段。

主要的 multi_match 模式 best_fieldsmost_fields 采用以字段为中心的查询视图。相比之下,combined_fields 以词为中心:operatorminimum_should_match 是按词而不是按字段应用的。具体而言,像这样的查询:

resp = client.search(
    query={
        "combined_fields": {
            "query": "database systems",
            "fields": [
                "title",
                "abstract"
            ],
            "operator": "and"
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      combined_fields: {
        query: 'database systems',
        fields: [
          'title',
          'abstract'
        ],
        operator: 'and'
      }
    }
  }
)
puts response
const response = await client.search({
  query: {
    combined_fields: {
      query: "database systems",
      fields: ["title", "abstract"],
      operator: "and",
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "combined_fields" : {
      "query":      "database systems",
      "fields":     [ "title", "abstract"],
      "operator":   "and"
    }
  }
}

执行为:

+(combined("database", fields:["title" "abstract"]))
+(combined("systems", fields:["title", "abstract"]))

换句话说,每个词都必须至少存在于一个字段中,才能使文档匹配。

cross_fields multi_match 模式也采用以词为中心的方法,并按词应用 operatorminimum_should_matchcombined_fields 相对于 cross_fields 的主要优点是它基于 BM25F 算法,其评分方法可靠且可解释。

自定义相似度

combined_fields 查询当前仅支持 BM25 相似度,除非配置了 自定义相似度,否则它是默认相似度。每个字段的相似度也不允许。在这些情况下使用 combined_fields 将导致错误。