# Libbeat common schema mapstriface

**URL:** <https://discuss.elastic.co/t/libbeat-common-schema-mapstriface/118678>\
**Category:** Beats\
**Tags:** beats-development\
**Created:** [February 6, 2018, 3:56pm UTC](https://discuss.elastic.co/t/libbeat-common-schema-mapstriface/118678 "2018-02-06T15:56:51Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![dcroonen](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dcroonen/32/27450_2.png) [@dcroonen](https://discuss.elastic.co/u/dcroonen)\
**Post date:** [February 6, 2018, 3:56pm UTC](https://discuss.elastic.co/t/libbeat-common-schema-mapstriface/118678/1 "2018-02-06T15:56:51Z")

</div>

Hi all

Am I missing something or is there a reason why there is no Float function (anymore) in mapstriface like in mapstrstr when converting events?

Kind regards  
Davy

---

<div class="post-metadata">

**Author:** ![exekias](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/exekias/32/28718_2.png) [@exekias](https://discuss.elastic.co/u/exekias)\
**Post date:** [February 6, 2018, 6:33pm UTC](https://discuss.elastic.co/t/libbeat-common-schema-mapstriface/118678/2 "2018-02-06T18:33:32Z")

</div>

Hi @dcroonen,

I think it never had it, probably because no one needed it? I'm just guessing here, not really sure 🙂

Could you explain a bit about the use you plan with it?

---

<div class="post-metadata">

**Author:** ![dcroonen](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dcroonen/32/27450_2.png) [@dcroonen](https://discuss.elastic.co/u/dcroonen)\
**Post date:** [February 7, 2018, 8:32am UTC](https://discuss.elastic.co/t/libbeat-common-schema-mapstriface/118678/3 "2018-02-07T08:32:43Z")

</div>

Hi @exekias,

Thanks for your reply and willingness to help. I'm pretty new when it comes to developing (metric)beats. Last week I started with a simple example where I pulled some data from a gearman daemon. For the mapping I used the mapstrstr library. In the example in the [manual](https://www.elastic.co/guide/en/beats/devguide/6.1/creating-metricsets.html) I saw the following mapping example in the schema definition:

```
            "test_float": c.Float("testFloat"),

```

Now I moved on to a more complex scenario where I pull individual queue data from a rabbitmq daemon. When I do a manual pull with curl I get the following json string (notice the float type in 'rate'):

```
{"memory":21840,"messages":0,"messages_details":{"rate":0.0},"messages_ready":0}

```

After unmarshalling it in Go I get the following 'nested' map[string]interface{}:

```
map[memory:21840 messages:0 messages_details:map[rate:0] messages_ready:0]

```

(I still have figure out why the type of 'rate' swithed from float to int but that's not relavant for the time being, I think) To write a schema for this I use the mapstriface library like this:

```
var (
schema = s.Schema{
    "memory": c.Int("memory"),
    "messages": c.Int("messages"),
    "messages_details": c.Dict("messages_details", s.Schema{
        "rate": c.Int("rate"),
    }), 
    "messages_ready": c.Int("messages_ready"),
})

```

Instead of using `c.Int("rate")`, I want to use `c.Float("rate")` to preserve the floating point character of the "rate" property. This is the reason for my initial question in this forum topic, any suggestions?

I tried to be as compact and clear as possible, if not, just ask. As I said I'm pretty new to this so maybe I'm missing some clues or doing things totally wrong....

Regards  
Davy

---

<div class="post-metadata">

**Author:** ![exekias](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/exekias/32/28718_2.png) [@exekias](https://discuss.elastic.co/u/exekias)\
**Post date:** [February 7, 2018, 10:16am UTC](https://discuss.elastic.co/t/libbeat-common-schema-mapstriface/118678/4 "2018-02-07T10:16:04Z")

</div>

You should be able to use Float, by usinng `mapstrstr` instead of `mapstriface`: [https://github.com/elastic/beats/blob/master/libbeat/common/schema/mapstrstr/mapstrstr.go#L88](https://github.com/elastic/beats/blob/master/libbeat/common/schema/mapstrstr/mapstrstr.go#L88)

For instance, it is used here: [https://github.com/elastic/beats/blob/master/metricbeat/module/redis/info/data.go#L22](https://github.com/elastic/beats/blob/master/metricbeat/module/redis/info/data.go#L22)

Br

---

<div class="post-metadata">

**Author:** ![dcroonen](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dcroonen/32/27450_2.png) [@dcroonen](https://discuss.elastic.co/u/dcroonen)\
**Post date:** [February 7, 2018, 12:35pm UTC](https://discuss.elastic.co/t/libbeat-common-schema-mapstriface/118678/5 "2018-02-07T12:35:26Z")

</div>

Ok, I understand, the schema definition would be then as follows:

```
    var (
        schema = s.Schema{
            "memory": c.Int("memory"),
            "messages": c.Int("messages"),
            "messages_details": s.Object{
                "rate": c.Float( **???** ),
            }, 
           "messages_ready": c.Int("messages_ready"),
    })

```

Only, how do I access the "messages\_details" "rate" property in the schema definition? In other words how do I acces a property in a nested map object in a schema definition?

> [@dcroonen](#):
>
> map[memory:21840 messages:0 messages\_details:map[rate:0] messages\_ready:0]

Regards  
Davy

---

<div class="post-metadata">

**Author:** ![steffens](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/steffens/32/79630_2.png) [@steffens](https://discuss.elastic.co/u/steffens)\
**Post date:** [February 7, 2018, 2:24pm UTC](https://discuss.elastic.co/t/libbeat-common-schema-mapstriface/118678/6 "2018-02-07T14:24:11Z")

</div>

The purpose of s.Schema is to introduce some schema translation with predefined namespacing. As you don't do any processing, but copy all contents you can just do `data = common.MapStr(parsedBody)`. Using Get/Set of MapStr you can modify the field to be float inplace.

mapstrstr is about mapping a flat key/value schema into a structured schema. This one expects the input value to be a string. As your source is json and the value is parsed as `json.Number`, the conversion via mapstrstr with Float converter might fail.  
mapstriface is about re-mapping a nested/structured schema originating from json documents. Unfortunately s.Float is missing in mapstriface. But adding `Float` should be quite simple by copy-paste-modify the [`Int` converter](https://github.com/elastic/beats/blob/master/libbeat/common/schema/mapstriface/mapstriface.go#L204) to generate a float value. `Float` missing from mapstriface is basically an oversight + no one ever needed it so far it seems. Btw. one can define custom converters the very same way `Int` is implemented.

Given the way schema did evolve over time (I haven't had a look at it since it was first introduced), I wonder if we can merge mapstrstr and mapstriface into one common package.

---

<div class="post-metadata">

**Author:** ![dcroonen](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dcroonen/32/27450_2.png) [@dcroonen](https://discuss.elastic.co/u/dcroonen)\
**Post date:** [February 7, 2018, 2:47pm UTC](https://discuss.elastic.co/t/libbeat-common-schema-mapstriface/118678/7 "2018-02-07T14:47:22Z")

</div>

Hi @steffens

Thanks a lot for your clarification. I already started suspecting something like this. I succeeded into to get a working example with `mapStrStr` but this involved to flatten my entire JSON document and to typecast every value to a `String`, not something very efficient in my opinion.

Because I don't need any remapping I will continue with your first suggestion.

Regards  
Davy

---

<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:** [March 7, 2018, 2:47pm UTC](https://discuss.elastic.co/t/libbeat-common-schema-mapstriface/118678/8 "2018-03-07T14:47:37Z")

</div>

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