ElasticSearch:如何创建复杂的查询&过滤嵌套对象?

时间:2015-11-27 22:07:59

标签: elasticsearch filter nested mapping

我有这个映射&查询。一切正常,除非我想用提到的" tagid" s过滤那些内容。它返回零结果。

我想根据标签ID过滤内容。

    {
  "mappings": {
    "video": {
      "_all": {
        "enabled": true
      },
      "properties": {
        "title": {
          "type": "string"
        },
        "en_title": {
          "type": "string"
        },
        "tags": {
          "type": "nested",
          "properties": {
            "tagname": {
              "type": "string"
            },
            "tagid": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "metadescription": {
          "type": "string"
        },
        "author": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "items": {
          "type": "nested",
          "properties": {
            "item_title": {
              "type": "string"
            },
            "item_duration": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "isfeatured": {
          "type": "string",
          "index": "not_analyzed"
        },
        "image": {
          "type": "string",
          "index": "not_analyzed"
        },
        "contenttype": {
          "type": "string",
          "index": "not_analyzed"
        },
        "category": {
          "type": "string",
          "index": "not_analyzed"
        },
        "categoryalias": {
          "type": "string",
          "index": "not_analyzed"
        },
        "url": {
          "type": "string",
          "index": "not_analyzed"
        },
        "authorid": {
          "type": "string",
          "index": "not_analyzed"
        },
        "price": {
          "type": "string",
          "index": "not_analyzed"
        },
        "duration": {
          "type": "string",
          "index": "not_analyzed"
        },
        "publishdate": {
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss"
        }
      }
    }
  }
}

这是查询:

    {
  "index": "content",
  "type": "video",
  "body": {
    "query": {
      "filtered": {
        "query": {
          "match_all": { }
        },
        "filter": {
          "bool": {
            "must": [
              {
                "nested": {
                  "path": "tags",
                  "query": {
                    "bool": {
                      "should": [
                        {
                          "term": {
                            "tagid": "193"
                          }
                        },
                        {
                          "term": {
                            "tagid": "194"
                          }
                        }
                      ]
                    }
                  }
                }
              },
              {
                "term": {
                  "categoryalias": "digilife"
                }
              },
              {
                "term": {
                  "price": 0
                }
              }
            ]
          }
        }
      }
    },
    "from": 0,
    "size": 9,
    "sort": [
      "_score"
    ]
  }
}

1 个答案:

答案 0 :(得分:0)

您的查询中的 nested filter 不太正确。对于您拥有tagid的字段名称,它应为tags.tagid。完整查询应

{
 "index": "content",
 "type": "video",
 "body": {
   "query": {
     "filtered": {
       "query": {
         "match_all": {}
       },
       "filter": {
         "bool": {
           "must": [{
             "nested": {
               "path": "tags",
               "query": {
                 "bool": {
                   "should": [{
                     "term": {
                       "tags.tagid": "193"
                     }
                   }, {
                     "term": {
                       "tags.tagid": "194"
                     }
                   }]
                 }
               }
             }
           }, {
             "term": {
               "categoryalias": "digilife"
             }
           }, {
             "term": {
               "price": 0
             }
           }]
         }
       }
     }
   },
   "from": 0,
   "size": 9,
   "sort": [
     "_score"
   ]
 }
}

修改

这是一个完整的工作示例,可帮助您入门。我已经使用了Sense,但您可以使用cURL或您选择的语言客户端。

用于映射

curl -XPUT "http://localhost:9200/content" -d'
{
  "mappings": {
    "video": {
      "_all": {
        "enabled": true
      },
      "properties": {
        "title": {
          "type": "string"
        },
        "en_title": {
          "type": "string"
        },
        "tags": {
          "type": "nested",
          "properties": {
            "tagname": {
              "type": "string"
            },
            "tagid": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "metadescription": {
          "type": "string"
        },
        "author": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "items": {
          "type": "nested",
          "properties": {
            "item_title": {
              "type": "string"
            },
            "item_duration": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "isfeatured": {
          "type": "string",
          "index": "not_analyzed"
        },
        "image": {
          "type": "string",
          "index": "not_analyzed"
        },
        "contenttype": {
          "type": "string",
          "index": "not_analyzed"
        },
        "category": {
          "type": "string",
          "index": "not_analyzed"
        },
        "categoryalias": {
          "type": "string",
          "index": "not_analyzed"
        },
        "url": {
          "type": "string",
          "index": "not_analyzed"
        },
        "authorid": {
          "type": "string",
          "index": "not_analyzed"
        },
        "price": {
          "type": "string",
          "index": "not_analyzed"
        },
        "duration": {
          "type": "string",
          "index": "not_analyzed"
        },
        "publishdate": {
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss"
        }
      }
    }
  }
}'

我们可以通过

检查映射是否符合预期
curl -XGET "http://localhost:9200/content/video/_mapping"

现在,让我们将一些文档索引到索引

// document with id 1
curl -XPOST "http://localhost:9200/content/video/1" -d'
{
    "tags": [
        {
            "tagname" : "tag 193",
            "tagid": "193"
        }        
    ],
    "price": 0,
    "categoryalias": "digilife"
}'

// document with id 2
curl -XPOST "http://localhost:9200/content/video/2" -d'
{
    "tags": [
        {
            "tagname" : "tag 194",
            "tagid": "194"
        }        
    ],
    "price": 0,
    "categoryalias": "digilife"
}'

// document with id 3
curl -XPOST "http://localhost:9200/content/video/3" -d'
{
    "tags": [
        {
            "tagname" : "tag 194",
            "tagid": "194"
        }        
    ],
    "price": 0,
    "categoryalias": "different category alias"
}'

现在,让我们运行查询。我删除了查询的多余部分并将其简化

curl -XGET "http://localhost:9200/content/video/_search" -d'
{
   "query": {
      "filtered": {
         "filter": {
            "bool": {
               "must": [
                  {
                     "nested": {
                        "path": "tags",
                        "query": {
                           "terms": {
                              "tags.tagid": [
                                 "193",
                                 "194"
                              ]
                           }
                        }
                     }
                  },
                  {
                     "term": {
                        "categoryalias": "digilife"
                     }
                  },
                  {
                     "term": {
                        "price": 0
                     }
                  }
               ]
            }
         }
      }
   },
   "size": 9
}'

只应返回包含ID 1和2的文档。这已通过结果确认

{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 2,
      "max_score": 1,
      "hits": [
         {
            "_index": "content",
            "_type": "video",
            "_id": "1",
            "_score": 1,
            "_source": {
               "tags": [
                  {
                     "tagname": "tag 193",
                     "tagid": "193"
                  }
               ],
               "price": 0,
               "categoryalias": "digilife"
            }
         },
         {
            "_index": "content",
            "_type": "video",
            "_id": "2",
            "_score": 1,
            "_source": {
               "tags": [
                  {
                     "tagname": "tag 194",
                     "tagid": "194"
                  }
               ],
               "price": 0,
               "categoryalias": "digilife"
            }
         }
      ]
   }
}