loopbackio / loopback-connector-elastic-search

Strongloop Loopback connector for Elasticsearch
MIT License
79 stars 56 forks source link

Automigrate when index or type does not exist yet #20

Closed fabien closed 9 years ago

fabien commented 9 years ago

Perhaps it's because I'm running an older ES version (1.2.1), but it seems that without any proper pre-checks and handling (indices.delete and indices.existsType), you're unable to run automigration in order to create a new index from scratch. @pulkitsinghal is this correct?

Here's my current monkey-patched solution:

var automigrate = dataSource.connector.automigrate;
dataSource.connector.automigrate = function(models, cb) {
    var self = this;
    var params = { index: self.settings.index };
    this.db.indices.delete(params, function(err, info) {
        if (err && err.message.indexOf('IndexMissingException') === -1) return cb(err);
        self.db.indices.create(params, function(err, info) {
            if (err) return cb(err);
            automigrate.call(self, models, cb);
        });
    });
};

var removeMappings = dataSource.connector.removeMappings;
dataSource.connector.removeMappings = function(modelNames, callback) {
    var self = this;
    var settings = this.settings;
    if (_.isFunction(modelNames)) {
        callback = modelNames;
        modelNames = _.pluck(settings.mappings, 'name');
    }
    var mappingsToRemove = _.filter(settings.mappings, function(mapping){
        return !modelNames || _.include(modelNames, mapping.name);
    });

    modelNames = _.pluck(mappingsToRemove, 'name');

    support.async.filter(modelNames, function(type, next) {
        self.db.indices.existsType({ index: settings.index, type: type }, next);
    }, function(filtered) {
        removeMappings.call(self, filtered, callback);
    });
};
pulkitsinghal commented 9 years ago

How about submitting a PR? I use "apiVersion": "1.1" when working with this module.

pulkitsinghal commented 7 years ago

@fabien - I was re-reviewing this and I had a few questions:

  1. What you did for the tests here:

    {
     elasticsearch: {
       type: 'Customer' // could set override here
    }

    Can the same thing be accomplished within a model's JSON file by setting datasource-specific options?

  2. You named it elasticsearch by default in the testcase. This was because of the rule:

    the value of this key must match the value of the corresponding connector property in datasources.json

    Correct?

  3. I haven't gotten to trial & error yet but would it be reasonable to assume that models could span separate indexes now? For example:

         User = db.define('User', {
           ...
         }, {
           elasticsearch: {
             index: red
           }
         });
    
         Customer = db.define('Customer', {
           ...
         }, {
           elasticsearch: {
             index: green
           }
         });