ElasticSearch:如何在一个或多个索引中跨所有类型搜索任意字段中的值?

37

我有两个索引my_index_1my_index_2,在这些索引中,我有以下文档类型:

my_index_1

  • 人员
  • 组织机构
  • 角色
  • 技能

my_index_2

  • 产品
  • 服务
  • 专利
  • 商标
  • 服务商标

每种类型都有不同的字段。

我的问题:如何以最佳方式查询任何类型的任何字段中的字符串“abc”,跨越一个或两个索引?

我没有在文档中看到任何便于这样搜索的内容。是否有类似以下的东西:

$ curl -XPOST 'localhost:9200/_search?pretty' -d '
{
  "query": { "match": { *: "abc" } }
}'

感谢您提前提供的任何帮助。

6个回答

43

你需要用 query_string 查询 或者 match 查询,这两个查询都可以满足你的需求。

如果没有在 default_field 中指定字段,query_string 将使用特殊的 _all 字段,这样就可以很好地工作。

curl -XPOST 'localhost:9200/_search?pretty' -d '{
  "query": { "query_string": { "query": "abc" } }
}'

使用match,您也可以仅指定_all

curl -XPOST 'localhost:9200/_search?pretty' -d '{
  "query": { "match": { "_all": "abc" } }
}'

请注意,使用query_string时,您可以使用通配符,但match不支持。


更新:

由于在6.0中已弃用_all字段,因此现在的解决方法是实现自定义所有字段


1
嗨,Val。谢谢你提供的两个选项。目前我可以使用带_all的匹配,但是将来我肯定需要更深入地了解query_string,因为我将需要使用通配符。所以,知道这些真是太好了。 - Information Technology
7
请注意,_all在6.0.0版本中已被弃用。请参见此处 - Faisal Mq
@FaisalMq 是的,现在的解决方法是实现一个自定义全字段 - Val

38

现在被弃用的_all字段的替代方案是多字段匹配查询

GET /_search
{
  "query": {
    "multi_match" : {
      "query":    "Will Smith",
      "fields": [ "important_field^5", "less_important^2", "title", "*_name" ] 
    }
  }
}

注意字段名称中的通配符以及使用^#语法增加字段重要性的支持。

从7.3版本开始: 如果没有提供字段,则multi_match查询默认为index.query.default_field索引设置,而该设置又默认为*。*提取映射中所有符合词项查询条件的字段并过滤元数据字段。然后将提取的所有字段组合在一起构建查询。

另一种选择是查询字符串查询

GET /_search
{
    "query": {
        "query_string" : {
            "query" : "(new york city) OR (big apple)",
            "default_field" : "content"
        }
    }
}

default_field (可选,字符串)如果在查询字符串中未提供字段,则希望搜索的默认字段。

默认为 index.query.default_field 索引设置,其默认值为 *。


1
谢谢,这可能是目前最相关的答案。帮了我很多! - Darragh Enright
尽管Val的答案也是正确的,但这个答案对我来说更具信息量和相关性。 - Nullius

3

尝试以下代码以获得所有索引和所有字段的结果:

GET _all/_search
{
"query" : {
   "multi_match": {
      "query": "abc",
      "fields": []
       }
    }
 }

2
我认为您可以使用_all来实现这个目的。
尝试一下吧。
$ curl -XPOST 'localhost:9200/_search?pretty' -d '
{
  "query": { "match": { "_all": "abc" } }
}'

您也可以使用query_string,因为它默认搜索_all


0
我使用的是 Elasticsearch 8.3 版本,但这些方法都对我不起作用。
适用于我的方法:
public function search($text)
{

    $client = $this->setClient();

    $params   = $this->transferRequiredFormat($text);
    $response = $client->search($params, $info = false);


    printf("Total docs: %d\n", $response['hits']['total']['value']);
    printf("Max score : %.4f\n", $response['hits']['max_score']);
    printf("Took      : %d ms\n", $response['took']);
    dd($response['hits']['hits']);


}

private function setClient()
{
    return ClientBuilder::create()->setHosts(['localhost:9200'])->build();
}

protected function transferRequiredFormat($text): array
{
    return [
        'index' => self::INDEX_NAME,
        'body'  => [
            'query' => [
                'query_string' => [
                    'query' => $text,
                ],
            ],
        ],
    ];
}

或者进行一项简短的调查文档

curl -X GET "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "query_string": {
      "query": "(new york city) OR (big apple)",
      "default_field": "content"
    }
  }
}


0
 $params = [
        'index' => 'my_index1,my_index2',
        'from'=>0,
        'size'=>10,
        'body'  => [
            'query' => [
                'bool' => [
                    'filter' => [
                        [
                            'query_string' => [
                                'query' => "info*"
                                //'query' => "*info*"
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ];

目前来看,你的答案还不够清晰。请[编辑]以添加更多详细信息,帮助其他人理解它是如何回答所提出的问题的。你可以在帮助中心找到如何撰写好的答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接