springloaded
springloaded

Reputation: 1089

How to define type for a specific field in ElasticSearch for Rails

I am struggling with elasticsearch-rails.

I have the following mapping:

{
  "listings" : {
    "mappings" : {
      "listing" : {
        "properties" : {
          "address" : {
            "type" : "string"
          },
          "authorized" : {
            "type" : "boolean"
          },
          "categories" : {
            "properties" : {
              "created_at" : {
                "type" : "date",
                "format" : "dateOptionalTime"
              },
              "id" : {
                "type" : "long"
              },
              "name" : {
                "type" : "string"
              },
              "parent_id" : {
                "type" : "long"
              },
              "updated_at" : {
                "type" : "date",
                "format" : "dateOptionalTime"
              },
              "url_name" : {
                "type" : "string"
              }
            }
          },
          "cid" : {
            "type" : "string"
          },
          "city" : {
            "type" : "string"
          },
          "country" : {
            "type" : "string"
          },
          "created_at" : {
            "type" : "date",
            "format" : "dateOptionalTime"
          },
          "featured" : {
            "type" : "boolean"
          },
          "geojson" : {
            "type" : "string"
          },
          "id" : {
            "type" : "long"
          },
          "latitude" : {
            "type" : "string"
          },
          "longitude" : {
            "type" : "string"
          },
          "name" : {
            "type" : "string"
          },
          "phone" : {
            "type" : "string"
          },
          "postal" : {
            "type" : "string"
          },
          "province" : {
            "type" : "string"
          },
          "thumbnail_filename" : {
            "type" : "string"
          },
          "updated_at" : {
            "type" : "date",
            "format" : "dateOptionalTime"
          },
          "url" : {
            "type" : "string"
          }
        }
      }
    }
  }
}

I would like to change the type for the geojson field from string to geo_point so I can use the geo_shape query on it.

I tried this in my model:

  settings index: { number_of_shards: 1 } do
    mappings dynamic: 'false' do
      indexes :geojson, type: 'geo_shape'
    end
  end

with peculiar results. When I queried the mapping with $ curl 'localhost:9200/_all/_mapping?pretty', the geojson field still shows as type: string.

Within a Rails console, if I do Listing.mappings.to_hash, it seems to show that the geojson field is of type geo_shape.

And yet when running this query:

Listing.search(query: { fuzzy_like_this: { fields: [:name], like_text: "gap" } }, query: { fuzzy_like_this_field: { city: { like_text: "San Francisco" } } }, query: { geo_shape: { geojson: { shape: { type: :envelope, coordinates: [[37, -122],[38,-123]] } } } }); response.results.total; response.results.map { |r| puts "#{r._score} | #{r.name}, #{r.city} (lat: #{r.latitude}, lon: #{r.longitude})" }

ES complains that the geojson field is not of type geo_shape.

What am I missing? How do I tell ES that I want the geojson field to be of type geo_shape and not string?

Upvotes: 0

Views: 1032

Answers (1)

springloaded
springloaded

Reputation: 1089

The issue was that I didn't delete and recreate the mapping.

In the rails console, I ran Model.__elasticsearch__.delete_index! and then Model.__elasticsearch__.create_index! followed by Model.import

Upvotes: 1

Related Questions