Strategy for multi-tenancy and custom fields in mapping

Hi everyone,

I'm new to Elasticsearch but I read several articles and a good part of the documentation. I learnt a lof of things but I have to admit I'm a little bit lost for my own use case.

I have a SaaS application with several companies. These companies can have contacts. And contacts can have several fields which are configured by each company (fields can be added, removed, etc...). Also, each contact can have other contacts as children (only 1 level of depth).

A little more information about the contact fields:

  • A company can edit the fields for his contacts
  • Fields can be of any existing type
  • They give a name to their fields
  • When contacts are imported from excel, iphone, ... new fields can automatically be created for thoses contacts

That means that each contact can have fields left empty, however their global mapping is the same (in the scope of the company)

For the multi-tenancy part of the problem I first thought about having one index per company, but after reading some articles and because I know I'll have a few big companies and a lot of small companies I'm now thinking about using routing with all small companies in the same index and big companies in their own index.

For the contacts part of the problem I don't know which solution I should have:

Having explicit mapping for contacts

I could create an explicit mapping for the contacts according to the fields the company had set.
This would possibly imply a reindex if the company updates an existing field, but adding new fields is ok and the reindex is something I could survive.

But, having multiple companies, thus, multiple types of contacts in the same index creates another problem: conflict in mapping field types...

I guess I could find another solution

Having contact fields as nested objects in the mapping

All contacts (from all companies) could have the same mapping, including a data field which is a nested object with a name field containing the name of the field, and several other fields for the different types I would like to handle, like: text_value, date_value, etc...

Changing contact fields would just be a matter of updating or deleting nested objects in the contacts. There is no more conflict in mapping field types as all contacts have the exact same mapping.
However, is it a good idea?

I would like to be able to search for contacts, eventually looking only for some fields (like having the firstname match "Fabien" for instance). Is it still possible with this mapping? Are the performances the same as with an explicit mapping like in the first solution?
Any pitfalls with this solution?

Questions

What do you think about these 2 solutions? Which one is better for my use case? Is there any other solution? How could I resolve the issues I have with these solutions?

Finally, is it possible to allow contacts to have child contacts and limit this association to 1 level? What would be the mapping for this?

Thank you for your help!

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