我正在使用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]],
],
],
],
],
];
答案 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"
}
}
]
}
}
}
}
}
}
}