# Mapping advice

**URL:** <https://discuss.elastic.co/t/mapping-advice/53740>\
**Category:** Elasticsearch\
**Created:** [June 23, 2016, 6:40am UTC](https://discuss.elastic.co/t/mapping-advice/53740 "2016-06-23T06:40:47Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mangetout](https://avatars.discourse-cdn.com/v4/letter/m/e47c2d/32.png) [@mangetout](https://discuss.elastic.co/u/mangetout)\
**Post date:** [June 23, 2016, 6:40am UTC](https://discuss.elastic.co/t/mapping-advice/53740/1 "2016-06-23T06:40:47Z")

</div>

Hello,

I am extremely new to elasticsearch so be gentle, please.

I would like to get some advice on a mapping problem I am facing. I know that a type, once set, cannot be changed so if it is a string has to be a string throughout the same index.

Let's say I have got recipes to store in ES. Recipes have ingredients and each ingredient has a name and a quantity

```auto
"ingredients": [
    {"name": "Eggs", "quantity": 3},
    ...
]

```

The problem I have got is that `quantity` can be expressed numerically or as a string (e.g. 'a tablespoon')

So the question is shall I treat everything as a string or are there some clever solutions to this very kind of mapping problem? And If I treat everything as a string, would I loose the possibility to query something like "give me recipes where eggs \> 3"?

Thank you for your advices.  
m.

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [June 23, 2016, 7:03am UTC](https://discuss.elastic.co/t/mapping-advice/53740/2 "2016-06-23T07:03:09Z")

</div>

> [@mangetout](#):
>
> I am extremely new to elasticsearch so be gentle, please.

We are always happy welcoming new users! 🙂

> [@mangetout](#):
>
> So the question is shall I treat everything as a string or are there some clever solutions to this very kind of mapping problem?

Well. My guess is that it won't work unless you send `"quantity": "3"`.

> [@mangetout](#):
>
> And If I treat everything as a string, would I loose the possibility to query something like "give me recipes where eggs \> 3"?

Yes. That's a problem.

What you could potentially do is to create a subfield and use for this subfield the `ignore_malformed` option: [ignore\_malformed | Elasticsearch Guide [2.3] | Elastic](https://www.elastic.co/guide/en/elasticsearch/reference/2.3/ignore-malformed.html)

So something like:

```auto
"quantity": {
  "type": "string",
  "fields": {
    "numeric": {
      "type": "integer",
      "ignore_malformed": true
    }
  }
}

```

I did not test it but that could work.

It means that you would be able to search for numerical values in `quantity.numeric`.

In 5.0.0, you can use [Node Ingest](https://www.elastic.co/guide/en/elasticsearch/reference/master/ingest.html) which would help you to transform your source by applying some mutation. And you can ignore failures as well.

---

<div class="post-metadata">

**Author:** ![mangetout](https://avatars.discourse-cdn.com/v4/letter/m/e47c2d/32.png) [@mangetout](https://discuss.elastic.co/u/mangetout)\
**Post date:** [June 23, 2016, 7:39am UTC](https://discuss.elastic.co/t/mapping-advice/53740/3 "2016-06-23T07:39:07Z")

</div>

Hello @dadoonet,

thank you for you reply.

After reading the `ignore_malformed` docs, I am not sure to understand what is going to be ignored in this case.

To store a recipe I would do something like this I suppose:

```auto
PUT recipes/tarte/1
{
    ...
    "ingredients": [
        {"name": "Eggs", "quantity": 3},
        {"name": "Salt", "quantity": "a pinch"},
        ...
    ]
    ...
}

```

So, shouldn't ES complain that I put `"quantity": 3` since my mapping declare it as a string? Do I have to add `ignore_malformed` to `quantity` as well?

Or maybe I should do something like:

```auto
PUT recipes/tarte/1
{
    ...
    "ingredients": [
        {"name": "Eggs", "quantity": "3"},
        {"name": "Salt", "quantity": "a pinch"},
        ...
    ]
    ...
}

```

So now the `numeric` field won't complain because it has `ignore_malformed` but does this mean that the the quantity for eggs has not been [indexed](https://www.elastic.co/guide/en/elasticsearch/reference/2.3/ignore-malformed.html#CO205-2)?

I am a bit confused, as you have might noticed 😃  
m

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [June 23, 2016, 8:25am UTC](https://discuss.elastic.co/t/mapping-advice/53740/4 "2016-06-23T08:25:15Z")

</div>

I believe you have to do the later but I did not test it...

Well. Should not be difficult to test both scenarios 😛

---

<div class="post-metadata">

**Author:** ![mangetout](https://avatars.discourse-cdn.com/v4/letter/m/e47c2d/32.png) [@mangetout](https://discuss.elastic.co/u/mangetout)\
**Post date:** [June 23, 2016, 10:37am UTC](https://discuss.elastic.co/t/mapping-advice/53740/5 "2016-06-23T10:37:53Z")

</div>

**UPDATE**

I just realised that I was running the search on `quantity` and not on `quantity.numeric`... damn you "Cut & Paste"...

It works! nicely.

**Ignore anything below this line!**

* * *

Ok, I've run some tests and they are not satisfactory at all.

Firstly I do the mappings somehow like @dadoonet suggested:

```auto
"quantity": {
  "type": "string",
  "fields": {
    "numeric": {
      "type": "integer",
      "ignore_malformed": true
    }
  }
}

```

Then I'll input some data like so:

```auto
PUT recipes/tarte/1
{
    ...
    "ingredients": [
        {"name": "Eggs", "quantity": "3"},
        {"name": "Salt", "quantity": "a pinch"},
        ...
    ]
    ...
}

PUT recipes/tarte/2
{
    ...
    "ingredients": [
        {"name": "Eggs", "quantity": "6"},
        {"name": "Sugar", "quantity": "200 gr."},
        ...
    ]
    ...
}

```

if now I query for recipes with any ingredient which has a quantity more than 5 I get the second one has expected, but unfortunately the `quantity.numeric` field even if it is an integer it is still sorted lexicographically, in fact if I put a recipes with 20 eggs and query again for something with quantity greater than 5 I still get one recipe back. Only If I query for `gte 2` I also get the 20 eggs recipe.

So, although it was promising, the trick is useless due to how the 'integer' is still treated as a 'string'.

I will need to re-think the structure I guess.

---

<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:** [July 5, 2017, 10:41pm UTC](https://discuss.elastic.co/t/mapping-advice/53740/6 "2017-07-05T22:41:08Z")

</div>


