Elasticsearch-dsl-py: [Question] How to represent a list/array of strings in persistence models

Created on 10 Mar 2015  路  7Comments  路  Source: elastic/elasticsearch-dsl-py

Hi, I need to represent this

PUT my_index/animal/4444
{

  "name": "Arara",
  "location": "Brasil",
  "colors": ["Yellow", "Green", "Blue"]
}

The above works nice and I can perform matches on colors

GET /myindexer/animal/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {
          "colors": "Blue"
        }}
      ]
    }
  }
}

{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 0.5,
      "hits": [
         {
            "_index": "my_index",
            "_type": "animal",
            "_id": "4444",
            "_score": 0.5,
            "_source": {
               "name": "Arara",
               "location": "Brasil",
               "colors": [
                  "Yellow",
                  "Green",
                  "Blue"
               ]
            }
         }
      ]
   }
}

So to represent the _colors_ list how can I do, is there a _List_ or _Array_ type?

class Animal(DocType):
    name = String()
    location = String()
    colors = List(String()) (????)

Most helpful comment

@abdelwahebmoalla you don't need to explicitly define a field as a list, just assign a list of values to it and it will work. if you want the default value of that field to be a list just specify multi=True when instantiating the field on your Document subclass:

from elasticsearch_dsl import Document, Keyword, Text

class BlogPost(Document):
    title = Text()
    content = Text()
    tags = Keyword(multi=True)

BlogPost.init()
bp = BlogPost()
bp.tags.append('tag1')
bp.save()

Hope this helps!

All 7 comments

If the following is ok (from docs)

assign some field values, can be values or lists of values

colors = String(fields={'raw': String(index='not_analyzed')})

Should I implement String field using those parameters? or a simple String() can support a list of values?

If so, is not better to have a explicit List() type?

The way I understand it, anything can be a list of objects.
So, you just have to make sure that your initialization of the attribute makes it a list, even if there is only one element in it:

>>> a = Animal(name="Dog", colors=["brown"])
>>> a.to_dict()
{"name": "Dog", "colors": ["brown"]}

Adding the fields= {'raw': String(index='not_analyzed')} has nothing to do with making the attribute a list or not. Is has to do with indexing.

If you have:

colors = String(fields={'raw': String(index='not_analyzed')})

Then you can search either colors, which will be an analyzed field, or you can search colors.raw, which will look for exact values.

For example, a search in color for "blue" will find "blue" of course, but also "light blue" and "dark blue". Whereas a search in color.raw for "blue" will only find "blue".

Thanks for the explanation @njoannin

Maybe it is a good idea to implement a List() field?

I want to implement a switch to make a field a list by default. It will be available for all the fields. It was described in #83

@rochacbruno You're welcome!
@HonzaKral I'd forgotten that suggestion you made of adding a switch. Looking forward to it :)

I still don't get how to implement a list field I used the type Keyword as a work arround but that's not the right impelementation

@abdelwahebmoalla you don't need to explicitly define a field as a list, just assign a list of values to it and it will work. if you want the default value of that field to be a list just specify multi=True when instantiating the field on your Document subclass:

from elasticsearch_dsl import Document, Keyword, Text

class BlogPost(Document):
    title = Text()
    content = Text()
    tags = Keyword(multi=True)

BlogPost.init()
bp = BlogPost()
bp.tags.append('tag1')
bp.save()

Hope this helps!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mortada picture mortada  路  3Comments

SalahAdDin picture SalahAdDin  路  4Comments

zahir-koradia picture zahir-koradia  路  3Comments

barseghyanartur picture barseghyanartur  路  4Comments

leoliuxd picture leoliuxd  路  4Comments