# Vector Tile API response id: (integer) Unique ID for the feature within the layer not found in hits or aggs layer

**URL:** <https://discuss.elastic.co/t/vector-tile-api-response-id-integer-unique-id-for-the-feature-within-the-layer-not-found-in-hits-or-aggs-layer/299952>\
**Category:** Elasticsearch\
**Created:** [March 17, 2022, 1:04pm UTC](https://discuss.elastic.co/t/vector-tile-api-response-id-integer-unique-id-for-the-feature-within-the-layer-not-found-in-hits-or-aggs-layer/299952 "2022-03-17T13:04:25Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Joseph\_Parish](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/joseph_parish/32/97848_2.png) [@Joseph\_Parish](https://discuss.elastic.co/u/Joseph_Parish)\
**Post date:** [March 17, 2022, 1:04pm UTC](https://discuss.elastic.co/t/vector-tile-api-response-id-integer-unique-id-for-the-feature-within-the-layer-not-found-in-hits-or-aggs-layer/299952/1 "2022-03-17T13:04:25Z")

</div>

Hi  
I am testing the Vector Tile API using this [repo](https://github.com/thomasneirynck/mvt_sample) which is an excellent tool.  
I would like to use the [feature-id](https://github.com/elastic/elasticsearch/issues/79585) within the hits layer of a polygon, but get this: Error: The feature id parameter must be provided.  
I do not find the id using:

```auto
map.on('click', () => {
// Find all features in one source layer in a vector source
const features = map.querySourceFeatures(sourceName, {
sourceLayer: renderMethod
})
console.log(JSON.stringify(features))
});

```

The Vector Tile API docs indicate that an id is contained in the response, but that does not appear to be the case or it is not being picked up on the client side.

---

<div class="post-metadata">

**Author:** ![Nathan\_Reese](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/nathan_reese/32/84829_2.png) [@Nathan\_Reese](https://discuss.elastic.co/u/Nathan_Reese)\
**Post date:** [March 17, 2022, 2:53pm UTC](https://discuss.elastic.co/t/vector-tile-api-response-id-integer-unique-id-for-the-feature-within-the-layer-not-found-in-hits-or-aggs-layer/299952/2 "2022-03-17T14:53:28Z")

</div>

@Joseph_Parish Thanks for bringing this up. I am seeing the same behavior.

For hits, `feature.id` is undefined, `feature.properties._id` contains the document id. For aggs, `feature.id` is undefined, `feature.properties._key` contains the bucket key.

This is confirmed in the Kibana integration tests. Notice the assert statement showing `feature.id` is getting returned as `undefined`.  
[https://github.com/elastic/kibana/blob/main/x-pack/test/api\_integration/apis/maps/get\_grid\_tile.js#L43](https://github.com/elastic/kibana/blob/main/x-pack/test/api_integration/apis/maps/get_grid_tile.js#L43)

```auto
      expect(clusterFeature.id).to.be(undefined);
      expect(clusterFeature.properties).to.eql({
        _count: 1,
        _key: '11/517/809',
        'avg_of_bytes.value': 9252,
      });

```

[https://github.com/elastic/kibana/blob/main/x-pack/test/api\_integration/apis/maps/get\_tile.js#L54](https://github.com/elastic/kibana/blob/main/x-pack/test/api_integration/apis/maps/get_tile.js#L54)

```auto
      expect(feature.id).to.be(undefined);
      expect(feature.properties).to.eql({
        '@timestamp': '1442709961071',
        _id: 'AU_x3_BsGFA8no6Qjjug',
        _index: 'logstash-2015.09.20',
        bytes: 9252,
        'machine.os.raw': 'ios',
      });

```

---

<div class="post-metadata">

**Author:** ![Ignacio\_Vera](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ignacio_vera/32/36674_2.png) [@Ignacio\_Vera](https://discuss.elastic.co/u/Ignacio_Vera)\
**Post date:** [March 17, 2022, 3:43pm UTC](https://discuss.elastic.co/t/vector-tile-api-response-id-integer-unique-id-for-the-feature-within-the-layer-not-found-in-hits-or-aggs-layer/299952/3 "2022-03-17T15:43:27Z")

</div>

Actually, vector tiles generated by the \_mvt API do not use the `id` defined in the standard. This `id` is numeric but Elasticsearch `ids` are strings, therefore we are adding those identifiers as properties of the feature (hits later contains an \_id property, aggs layer contains a ~~\_bucket~~ \_key property).

I have opened a PR to correct the documentation:

> <https://github.com/elastic/elasticsearch/pull/85067>
>
> Vector tiles search documentation claims that the final vector tiles contains fo…r each feature and identifier as an integer in the form of \`feature.id\`. This is part of the standard and those ids are numeric.
> 
> Elasticsearch document ids are not numeric but strings and therefore we are not using the ids from the standards but adding ES ids as a properties of the feature. In the case of the hits layer, each feature contains an \`\_id\` property and for the aggs layer, each feature contains a \`\_bucket\` property. 
> 
> This PR removes the reference to the integer identifier from the docs.
> 
> https://elasticsearch\_85067.docs-preview.app.elstc.co/guide/en/elasticsearch/reference/master/search-vector-tile-api.html

---

<div class="post-metadata">

**Author:** ![thomasneirynck](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/thomasneirynck/32/23313_2.png) [@thomasneirynck](https://discuss.elastic.co/u/thomasneirynck)\
**Post date:** [March 17, 2022, 5:53pm UTC](https://discuss.elastic.co/t/vector-tile-api-response-id-integer-unique-id-for-the-feature-within-the-layer-not-found-in-hits-or-aggs-layer/299952/4 "2022-03-17T17:53:54Z")

</div>

@Joseph_Parish apart from the answers provided by @Ignacio_Vera and @Nathan_Reese , maybe tangential comment.

I noticed you are using `querySourceFeatures` on a click-event. You might want to use `queryRenderedFeatures` ([https://maplibre.org/maplibre-gl-js-docs/api/map/#map#queryrenderedfeatures](https://maplibre.org/maplibre-gl-js-docs/api/map/#map#queryrenderedfeatures)) instead.

That is the method Kibana is using to query for features on a click-event: [kibana/tooltip\_control.tsx at e08712deef91950d1edca03af2133045206d4211 · elastic/kibana · GitHub](https://github.com/elastic/kibana/blob/e08712deef91950d1edca03af2133045206d4211/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.tsx#L350-L352) (e.g. for tooltip on `onClick` event).

It takes into account the styling of the feature (e.g. line-thickness, symbol-size...). It targets a "layer", not a "source".

`querySourceFeatures` is lower level, grabbing all data in the visible tiles, and generally not the best to attach to a click-event.

---

<div class="post-metadata">

**Author:** ![Joseph\_Parish](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/joseph_parish/32/97848_2.png) [@Joseph\_Parish](https://discuss.elastic.co/u/Joseph_Parish)\
**Post date:** [March 17, 2022, 7:22pm UTC](https://discuss.elastic.co/t/vector-tile-api-response-id-integer-unique-id-for-the-feature-within-the-layer-not-found-in-hits-or-aggs-layer/299952/5 "2022-03-17T19:22:57Z")

</div>

Thanks for the quick replies! Actually I started with queryRenderedFeatures and then added querySourceFeatures when not finding a feature id in the geoJson. I am a bit unclear on the resolution. Is it correct that the id will be added as a string value (and docs fixed) ? The Mapbox GL feature states [docs](https://docs.mapbox.com/mapbox-gl-js/api/#map#setfeaturestate) state that the feature.id can be an integer or a string, but supports string values only when ... the string can be cast to an integer.

We use the feature state for a variety of data styling & joining configs starting with this ([simple example])([Create a hover effect | Mapbox GL JS | Mapbox](https://docs.mapbox.com/mapbox-gl-js/example/hover-styles/)). The Vector API is huge development for our app and we are in the process of changing out pre-generated tiles for tiles served from this API

---

<div class="post-metadata">

**Author:** ![Ignacio\_Vera](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ignacio_vera/32/36674_2.png) [@Ignacio\_Vera](https://discuss.elastic.co/u/Ignacio_Vera)\
**Post date:** [March 18, 2022, 6:43am UTC](https://discuss.elastic.co/t/vector-tile-api-response-id-integer-unique-id-for-the-feature-within-the-layer-not-found-in-hits-or-aggs-layer/299952/6 "2022-03-18T06:43:26Z")

</div>

> [@Joseph\_Parish](#):
>
> Is it correct that the id will be added as a string value (and docs fixed) ? The Mapbox GL feature states [docs](https://docs.mapbox.com/mapbox-gl-js/api/#map#setfeaturestate) state that the feature.id can be an integer or a string, but supports string values only when ... the string can be cast to an integer.

As you noted, ids can have different data types as long as they are integers 🙂 So no, we are not going to add values to those ids because our ids are not integers.

Unique identifiers are already added to the vector tiles as properties. In the hits layer you can find a property called `_id` and in the aggs layer you can find a property called `_key`.

See here how to use a property as an id field : [An option to use a feature property as ID for feature state by mourner · Pull Request #8987 · mapbox/mapbox-gl-js · GitHub](https://github.com/mapbox/mapbox-gl-js/pull/8987)

---

<div class="post-metadata">

**Author:** ![Joseph\_Parish](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/joseph_parish/32/97848_2.png) [@Joseph\_Parish](https://discuss.elastic.co/u/Joseph_Parish)\
**Post date:** [March 18, 2022, 8:26pm UTC](https://discuss.elastic.co/t/vector-tile-api-response-id-integer-unique-id-for-the-feature-within-the-layer-not-found-in-hits-or-aggs-layer/299952/7 "2022-03-18T20:26:32Z")

</div>

Thanks I had assumed the promoteId was for GeoJson data sources only. This offers way more flexibility

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [April 15, 2022, 8:26pm UTC](https://discuss.elastic.co/t/vector-tile-api-response-id-integer-unique-id-for-the-feature-within-the-layer-not-found-in-hits-or-aggs-layer/299952/8 "2022-04-15T20:26:56Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
