Elasticsearch:如何仅检索所需的嵌套对象

时间:2016-01-03 18:04:36

标签: java elasticsearch

我的Elasticsearch索引具有以下映射结构。

{
  "users": {
    "mappings": {
      "user-type": {
        "properties": {
          "lastModifiedBy": {
            "type": "string"
          },
          "lastModifiedDate": {
            "type": "date",
            "format": "dateOptionalTime"
          },
          "details": {
            "type": "nested",
            "properties": {
              "lastModifiedBy": {
                "type": "string"
              },
              "lastModifiedDate": {
                "type": "date",
                "format": "dateOptionalTime"
              },
              "views": {
                "type": "nested",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "properties": {
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "type": {
                        "type": "string"
                      },
                      "value": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

基本上我想根据索引id& amp来检索详细信息中的视图对象。 view id(details.views.id)。

我尝试过使用下面的java代码。但似乎无法正常工作。

SearchRequestBuilder srq =  this.client.prepareSearch(this.indexName)
    .setTypes(this.type)
    .setQuery(QueryBuilders.termQuery("_id", sid))
    .setPostFilter(FilterBuilders.nestedFilter("details.views", 
         FilterBuilders.termFilter("details.views.id", id)));

以下是此java代码的查询结构。

{
  "query": {
    "term": {
      "_id": "123"
    }
  },
  "post_filter": {
    "nested": {
      "filter": {
        "term": {
          "details.views.id": "def"
        }
      },
      "path": "details.views"
    }
  }
}

1 个答案:

答案 0 :(得分:0)

由于nestedviewdetails嵌套在nested内,您基本上也需要两个_id过滤器(每个级别一个)+对{ "query": { "ids": { "values": [ "123" ] } }, "post_filter": { "nested": { "filter": { "nested": { "path": "details.view", "filter": { "term": { "details.views.id": "def" } } } }, "path": "details" } } } 字段的约束最好使用ids query。查询DSL看起来像这样:

// 2nd-level nested filter
FilterBuilder detailsView = FilterBuilders.nestedFilter("details.views", 
    FilterBuilders.termFilter("details.views.id", id));

// 1st-level nested filter
FilterBuilder details = FilterBuilders.nestedFilter("details", detailsView);

// ids constraint
IdsQueryBuilder ids = QueryBuilders.idsQuery(this.type).addIds("123");

SearchRequestBuilder srq =  this.client.prepareSearch(this.indexName)
   .setTypes(this.type)
   .setQuery(ids)
   .setPostFilter(details);

将其转换为Java代码会产生:

class PDF extends FPDF
{
    public function Header() {
        $this->Cell(0, 8, "HEADER TEXT", 0, 0, 'R');
    }
}

PS:我是@Paul所说的第二个,即首先使用查询DSL,当你知道你已经找到了你需要的确切查询时,你可以将它翻译成Java形式。