title: NodeJs connecting to elasticsearch
body: <p>I am trying to update my REST API to use elasticsearch, I found the mongoosastic plugin which seems to be the best solution but I cannot find out how to connect elasticsearch with the node server.</p>
  
  <p>According to the mongoosastic doc (<a href="https://github.com/mongoosastic/mongoosastic" rel="nofollow noreferrer">https://github.com/mongoosastic/mongoosastic</a>), the code in user.model.ts should work, however when I create an user then hit <a href="http://localhost:9200/user/user/_search" rel="nofollow noreferrer">http://localhost:9200/user/user/_search</a> the body is the following json :</p>
  
  <pre><code>{
      "error": {
          "root_cause": [{
              "type": "index_not_found_exception",
              "reason": "no such index",
              "resource.type": "index_or_alias",
              "resource.id": "user",
              "index_uuid": "_na_",
              "index": "user"
          }],
          "type": "index_not_found_exception",
          "reason": "no such index",
          "resource.type": "index_or_alias",
          "resource.id": "user",
          "index_uuid": "_na_",
          "index": "user"
      },
      "status": 404
  }
  </code></pre>
  
  <p>When creating a new user, I have the following error in the console :</p>
  
  <pre><code>POST http://0.0.0.0:9200/users/user/5b9e535a6a2a4100cb86e9a3?refresh=true =&gt; connect ECONNREFUSED 0.0.0.0:9200
      at Log.error (/app/node_modules/elasticsearch/src/lib/log.js:226:56)
      at checkRespForFailure (/app/node_modules/elasticsearch/src/lib/transport.js:259:18)
      at HttpConnector.&lt;anonymous&gt; (/app/node_modules/elasticsearch/src/lib/connectors/http.js:163:7)
      at ClientRequest.wrapper (/app/node_modules/elasticsearch/node_modules/lodash/lodash.js:4949:19)
      at ClientRequest.emit (events.js:182:13)
      at Socket.socketErrorListener (_http_client.js:391:9)
      at Socket.emit (events.js:182:13)
      at emitErrorNT (internal/streams/destroy.js:82:8)
      at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
      at process._tickCallback (internal/process/next_tick.js:63:19)
  ::ffff:172.18.0.1 - - [16/Sep/2018:12:58:02 +0000] "POST /api/v0/user/ HTTP/1.1" 201 230 "http://localhost:9000/doc/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36"
  Elasticsearch WARNING: 2018-09-16T12:58:02Z
    Unable to revive connection: http://0.0.0.0:9200/
  Elasticsearch WARNING: 2018-09-16T12:58:02Z
    No living connections
  </code></pre>
  
  <p>So I believe the error is just some config options that I have misconfigured but I can't find out what I have done wrong.</p>
  
  <p>Going to <a href="http://localhost:9200/_cluster/health" rel="nofollow noreferrer">http://localhost:9200/_cluster/health</a> via the browser give me :</p>
  
  <pre><code>{
      "cluster_name": "docker-cluster",
      "status": "yellow",
      "timed_out": false,
      "number_of_nodes": 1,
      "number_of_data_nodes": 1,
      "active_primary_shards": 1,
      "active_shards": 1,
      "relocating_shards": 0,
      "initializing_shards": 0,
      "unassigned_shards": 1,
      "delayed_unassigned_shards": 0,
      "number_of_pending_tasks": 0,
      "number_of_in_flight_fetch": 0,
      "task_max_waiting_in_queue_millis": 0,
      "active_shards_percent_as_number": 50.0
  }
  </code></pre>
  
  <p>I also use docker.</p>
  
  <p>Dockerfile :</p>
  
  <pre><code>FROM mhart/alpine-node:10
  ADD . /app
  WORKDIR /app
  RUN apk --no-cache add --virtual builds-deps build-base python &amp;&amp;\
      yarn global add nodemon &amp;&amp;\
      yarn &amp;&amp;\
      apk del builds-deps build-base python
  </code></pre>
  
  <p>docker-compose.yml: </p>
  
  <pre><code>version: "3.3"
  services:
    api:
  
      build: .
      links:
        - 'mongo:mongo'
        - 'elasticsearch:elasticsearch'
      env_file:
        - .env
      volumes:
        - .:/app
        - /app/node_modules
      ports:
        - "0.0.0.0:9000:9000"
      command: sh -c "mkdir -p dist &amp;&amp; touch ./dist/app.js &amp;&amp; yarn run start"
  
    transpiler:
      build: .
      volumes:
        - .:/app
        - /app/node_modules
      command: yarn run transpile -- -w
  
    linter:
      build: .
      volumes:
        - .:/app
        - /app/node_modules
      command: nodemon --delay 500ms --exec yarn run lint
  
    mongo:
      image: mongo:4.0
      ports:
        - "27017"
      command: mongod
      volumes:
        - ./data:/data/db
  
    elasticsearch:
      image: docker.elastic.co/elasticsearch/elasticsearch:6.1.1
      volumes:
        - ./esdata:/esdata
      environment:
        - bootstrap.memory_lock=true
        - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
        - discovery.type=single-node
      ports:
        - "9300:9300"
        - "9200:9200"
  
    mocha:
      build: .
      volumes:
        - .:/app
        - /app/node_modules
      links:
        - 'mongo:mongo'
      command: nodemon --delay 500ms --exec yarn run test
      env_file:
        - .env
      environment:
        NODE_ENV: 'test'
  </code></pre>
  
  <p>user.model.ts</p>
  
  <pre><code>import * as mongoose from 'mongoose'
  import * as mongoosastic from 'mongoosastic'
  import * as elasticsearch from 'elasticsearch'
  import * as bcrypt from 'bcrypt'
  import * as emailValidator from 'email-validator'
  import { IImage, Image } from '../image/image.model'
  import config from '../../config/environment'
  import { NextFunction } from 'express'
  import * as beautifyUnique from 'mongoose-beautiful-unique-validation'
  
  const SALT_WORK_FACTOR: number = config.bcryptWorkFactor
  
  export interface IUser extends mongoose.Document {
      mail: string
      password: string
      login: string
      profilPic: mongoose.Types.ObjectId
      public: {
          mail: string
          profilPic: mongoose.Types.ObjectId
          login: string
      }
  }
  
  const UserSchema: mongoose.Schema = new mongoose.Schema({
      login: {
          required: true,
          type: String,
          unique: 'Le nom d\'utilisateur `{VALUE}` est déjà utilisé'
      },
      mail: {
          required: true,
          type: String,
          unique: 'Le mail `{VALUE}` est déjà utilisé'
      },
      password: { required: true, type: String, select: false },
      profilPic: { type: mongoose.Schema.Types.ObjectId, ref: 'Image' },
  }, { timestamps: true })
  
  UserSchema.virtual('public').get(function (): object {
      return {
          id: this.id,
          mail: this.mail,
          profilPic: this.profilPic,
          login: this.login,
      }
  })
  
  UserSchema.pre&lt;IUser&gt;('save', function (next: NextFunction): void {
      // If user already have a picture no need to set the default one
      if (this.profilPic) {
          return next()
      }
      const imgProfil: IImage = new Image({
          name: 'default.png',
          link: config.assetsURI + 'user/profil/default.png',
          type: 'png',
          width: 502,
          height: 502,
      })
      Image.create(imgProfil).then((img: IImage) =&gt; {
          this.profilPic = img.id
          return next()
      }).catch((error: Error) =&gt; {
          return next(error)
      })
  })
  
  UserSchema.method('comparePassword',
      (password: string, hash: string): Promise&lt;boolean&gt; =&gt; {
          return bcrypt.compare(password, hash)
              .then((value: boolean) =&gt; {
                  return value
              })
      })
  
  UserSchema.method('hashPassword',
      (password: string): Promise&lt;string&gt; =&gt; {
          return bcrypt.hash(password, SALT_WORK_FACTOR)
              .then((hashedPassword: string) =&gt; {
                  return hashedPassword
              })
      })
  
  UserSchema.static('validEmail', (email: string): boolean =&gt; {
      return emailValidator.validate(email)
  })
  
  UserSchema.set('toJSON', {
      transform: (doc: IUser, ret: IUser): void =&gt; {
          ret.id = ret._id
          delete ret._id
          delete ret.__v
      }
  })
  
  UserSchema.plugin(beautifyUnique)
  const esClient: elasticsearch.Client = new elasticsearch.Client({
      host: '0.0.0.0:9200'
  })
  UserSchema.plugin(mongoosastic, {
      esClient: esClient
  })
  export const User: mongoose.Model&lt;IUser&gt; =
      mongoose.model&lt;IUser&gt;('User', UserSchema)
  </code></pre>