django-elasticsearch-dsl icon indicating copy to clipboard operation
django-elasticsearch-dsl copied to clipboard

How do you map a ManyToMany field to a DocType class?

Open sillyfatcat opened this issue 7 years ago • 4 comments

My model has a few foreign keys/manytomany fields but I'm not entirely sure how to handle it with elasticsearch-dsl.

class HouseIndex(DocType):
    house_type = String()
    #people
    sold = Boolean()
    built_datetime = Date()
    #alerts
    # associated_locations
    hash = String()


class House(models.Model):
    house_type = models.ForeignKey(HouseType, db_index=True,
                                   on_delete=models.CASCADE)
    people = models.ManyToManyField(to='Person', db_index=True,
                                      through='PersonToHouseMap')
    sold = models.BooleanField(default=False)
    built_datetime = models.DateTimeField()
    alerts = models.ManyToManyField(Alert)
    associated_locations = models.ManyToManyField(to='Location')
    hash = models.CharField(max_length=64, unique=True, null=True)
    objects = HouseManager()

But I'm not sure what to do when it's a ManyToMany field. Such as with people, alerts, and associated locations. Any guidance would be appreciated

sillyfatcat avatar Jan 02 '18 23:01 sillyfatcat

Hi! @sshum00 Have you solved this problem yet? I also encountered the same problem

zhaokefei avatar Jan 08 '18 06:01 zhaokefei

I've not solved this problem yet

sillyfatcat avatar Jan 08 '18 17:01 sillyfatcat

According to the documentation, this can be done

  class HouseIndex(DocType):
      house_type = fields.ObjectField(properties={
          'name': fields.StringField()
      })
      people = fields.NestedField(properties={
          'name': fields.StringField()
      })

zhaokefei avatar Jan 15 '18 07:01 zhaokefei

I am not sure why NestedField did not work for me but in the end, I just turned everything into a string as follows

    alerts = fields.StringField()

    def prepare_alerts(self, instance):
        return ' '.join([alert.name for alert in instance.alerts.all()])

It is not the prettiest method but it can handle whatever type of fields I need to index.

BoPeng avatar Jul 05 '24 19:07 BoPeng