我正在使用ElasticSearch的php包在我的Laravel应用程序中实现ElasticSearch。
我的应用程序是一个小型工作台,当前我的工作文档如下所示:
{
"_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]],
],
],
],
],
];
最佳答案
您需要指定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"
}
}
]
}
}
}
}
}
}
}
关于php - 数组中的ElasticSearch匹配组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28764996/