masumsoft / express-cassandra

Cassandra ORM/ODM/OGM for NodeJS with support for Apache Cassandra, ScyllaDB, Datastax Enterprise, Elassandra & JanusGraph.
http://express-cassandra.readthedocs.io
GNU Lesser General Public License v3.0
231 stars 68 forks source link

Elassandra support broken #195

Open shazy792 opened 5 years ago

shazy792 commented 5 years ago

express-cassandra error: To use elassandra features, set "manageESIndex" to true in ormOptions

manageESIndex has been set to true in the config.

Here is my config for reference

{
  clientOptions: {
    contactPoints: ['172.17.0.2'],
    protocolOptions: { port: 9042 },
    keyspace: 'mykeyspace',
    queryOptions: { consistency: expressCassandra.consistencies.one },
  },
  ormOptions: {
    defaultReplicationStrategy: {
      class: 'NetworkTopologyStrategy',
      DC1: 1
    },
    manageESIndex: true,
    migration: 'alter'
  }
}
Sayah-Sel commented 11 months ago

Up.

Elassandra support is still broken.

It seem to be pretty deep, I think it would need several fixes.

Are there people motivated to try to patch this together?

I have already roughly located the problem.

The error appears in the base_model.js file: BaseModel.get_es_client = function f() { if (!this._properties.esclient) { throw new Error('To use elassandra features, setmanageESIndexto true in ormOptions'); } return this._properties.esclient; };

However it source seem to be in the in lib/orm/apollo.js

As one can see there is no elastic search client, it is because it is in fact never created. The apollo classe defined several methods which use others state variable _this1 and _this2 which are copy (and not reference) from this, so finally the this.esclient do not exist.

It may be due to a change of js behaviour with the versions of node.

Its existence is easily patched, however elasticsearch indexing ask for more work, and I am quite blocked for now.

masumsoft commented 11 months ago

@Sayah-Sel which version of node and elassandra you're trying with? Currently only elassandra version 5.5.x is supported. For v6 there was a pending issue in elassandra that was needed to be fixed to keep it supported: https://github.com/strapdata/elassandra/issues/256

But it looks like the elassandra project is no longer actively maintained and the issue is still open there.

Sayah-Sel commented 11 months ago

I use Elassandra 5.5.0.22

And node 16.18

So Elassandra is also abandoned, I suspected it a little but not much...

Sayah-Sel commented 11 months ago

@masumsoft and btw, thank you for your answer!

To be honest I am quite relief to discover that YOU did not abandonned express-cassandra, I feel less alone in this World 😅😅

I don't feel like I am using advanced features of Cassandra/Elassandra/Elasticsearch/Express-Cassandra, so if it is only a problems of version on those I should be able to use a more ancient without problems.

But change my node version would certainly be much harder, but perhaps not unfeasible. When I begun my app I thought backend code was the more difficult, but with time its look more and more like copy-past each time i create a new controller file and Cassandra table. So a change of node version may break all my code, but nothing definitive...

But anyway, I would prefer a way of make everything work if the newest versions possibles of everyone. A project that is stuck on ancient version is condemned with time it can only become less and less competitive...

(not as simple as that now that I hear that Elassandra is abandonned, that's a big problem...)

Another question for now, did you read about the support of Vector Search in Cassandra 5.0 ? Do you think in my replace efficiently Elastic-Search and so Elassandra ?

If so it would be much more reliable as it is a core part of the Cassandra project, and not a distinct project.

Sayah-Sel commented 11 months ago

Anyway, to continue on more serious considerations.

I try to understand how you intend to get the elasticsearch clients created. And I was not able too. ES and Janus Graph clients seem to be handled as "managementTasks" only in a init callback: ` init(callback) { const onUserDefinedAggregates = (err) => { if (err) { callback(err); return; }

    const managementTasks = [];
    if (this._keyspace && this._options.manageESIndex) {
      this.assertESIndexAsync = Promise.promisify(this._assert_es_index);
      managementTasks.push(this.assertESIndexAsync());
    }
    if (this._keyspace && this._options.manageGraphs) {
      this.assertGremlinGraphAsync = Promise.promisify(this._assert_gremlin_graph);
      managementTasks.push(this.assertGremlinGraphAsync());
    }
    Promise.all(managementTasks)
      .then(() => {
        callback(null, this);
      })
      .catch((err1) => {
        callback(err1);
      });
  };

... } `

I don't get when this is called (but I know it is, as I putted a console.log inside...), however it seem that this._esclient loaded in baseProperties is still null.

So i tried to create one myself on the model of create_es_client and _assert_es_index functions: var esClient = this.create_es_client() const keyspaceName = this._keyspace; const mappingName =modelName; const indexName =${keyspaceName}_${mappingName}`; console.log(keyspaceName)

const elassandraBuilder = new ElassandraBuilder(esClient);
elassandraBuilder.assert_index(keyspaceName, indexName, function (err) {});
this._esclient = elassandraBuilder._client;

`

So now, I have a client, I can call it, and send ES queries.

It works... Except that the queries does not find anything, however, there is actually hope. Because I just discovered that if I follow the following exemple of the doc (with model name) and call myself the client and provide type and index field it works:

` const esClient = models.instance.User.get_es_client(); const modelKeyspaceName = models.instance.MultipleOrderBy.get_keyspace_name(); const modelTableName = models.instance.User.get_tablename(); const modelIndexName = modelKeyspaceName + '' + modelTableName;

esClient.count({
    index: modelIndexName,
    type: modelTableName
}, function(err, response) {
    if (err) throw err;

    console.log(response.count);
});

`

Not so bad, I suppose, I just feel like I am missing something.