ElasticSearch匹配数组中的组合

时间:2015-02-27 12:20:21

标签: php search laravel elasticsearch

我正在使用ElasticSearch的php包将ElasticSearch实现到我的Laravel应用程序中。

我的应用程序是一个小工作板,目前我的工作文件看起来像这样:

{  
   "_index":"jobs",
   "_type":"job",
   "_id":"19",
   "_score":1,
   "_source":{  
      "0":"",
      "name":"Programmer",
      "description":"This is my first job! :)",
      "text":"Programming is awesome",
      "networks":[  
         {  
            "id":1,
            "status":"PRODUCTION",
            "start":"2015-02-26",
            "end":"2015-02-26"
         },
         {  
            "id":2,
            "status":"PAUSE",
            "start":"2015-02-26",
            "end":"2015-02-26"
         }
      ]
   }
}

您可以看到作业可以附加到多个网络。在我的搜索查询中,我想包含WHERE network.id == 1 AND network.status == PRODUCTION.

我当前的查询看起来像这样,但如果它具有任何状态为PRODUCTION的网络,则返回具有id为1的网络的文档。无论如何,我可以在一个网络中强制执行两者都是真的吗?

$query = [
            'index' => $this->index,
            'type' => $this->type,
            'body' => [
                'query' => [
                    'bool' => [
                        'must' => [
                            ['networks.id' => 1]],
                            ['networks.status' => 'PRODUCTION']]
                        ],
                        'should' => [
                            ['match' => ['name' => $query]],
                            ['match' => ['text' => $query]],
                            ['match' => ['description' => $query]],
                        ],
                    ],
                ],
            ],
        ];

1 个答案:

答案 0 :(得分:3)

您需要指定networks数组中的对象应作为单个对象存储在索引中,这样您就可以对单个network对象执行搜索。您可以使用Elasticsearch中的nested type执行此操作。

此外,如果您进行完全匹配,最好使用过滤器而不是查询,因为过滤器是缓存的,并且始终为您提供比查询更好的性能。

使用新映射创建索引。对nested数组使用networks类型。

POST /test
{
    "mappings": {
        "job": {
            "properties": {
                "networks": {
                    "type": "nested",
                    "properties": {
                        "status": {
                            "type": "string",
                            "fields": {
                                "raw": {
                                    "type": "string",
                                    "index": "not_analyzed"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

添加文档:

POST /test/job/1
{
    "0": "",
    "name": "Programmer",
    "description": "This is my first job! :)",
    "text": "Programming is awesome",
    "networks": [
        {
            "id": 1,
            "status": "PRODUCTION",
            "start": "2015-02-26",
            "end": "2015-02-26"
        },
        {
            "id": 2,
            "status": "PAUSE",
            "start": "2015-02-26",
            "end": "2015-02-26"
        }
    ]
}

由于您有嵌套类型,因此需要使用嵌套过滤器。

POST /test/job/_search
{
    "query": {
        "filtered": {
            "query": {
                "match_all": {}
            },
            "filter": {
                "nested": {
                    "path": "networks",
                    "filter": {
                        "bool": {
                            "must": [
                                {
                                    "term": {
                                        "networks.id": "1"
                                    }
                                },
                                {
                                    "term": {
                                        "networks.status.raw": "PRODUCTION"
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        }
    }
}