Check version of Elasticsearch

$ curl -XGET 'localhost:9200'
>result:
{
  "name" : "Caprice",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "5.0.0-alpha4",
    "build_hash" : "3f5b994",
    "build_date" : "2016-06-27T16:23:46.861Z",
    "build_snapshot" : false,
    "lucene_version" : "6.1.0"
  },
  "tagline" : "You Know, for Search"
}

Test Elasticsearch Custom Analyzer, kr_analyzer

    1. Deleting ‘blogs’ index if exists
curl -XDELETE localhost:9200/blogs
    1. Creating ‘blogs’ index having index settings and mappings
curl -XPUT 'http://localhost:9200/blogs?pretty' -d '{
  "settings": {
    "analysis": {
      "analyzer": {
        "kr_analyzer": {
          "type": "custom",
          "tokenizer": "kr_tokenizer",
          "filter": ["trim", "lowercase","english_stop", "en_snow", "kr_filter"]
        }
      },
      "filter": {
        "en_snow": {
          "type": "snowball",
          "language": "English"
        },
        "english_stop": {
          "type":       "stop",
          "stopwords":  "_english_"
        }
      }
    }
  },
  "mappings": {
    "blog": {
      "_all": {
        "analyzer": "kr_analyzer", 
        "search_analyzer": "kr_analyzer"
      }
    }
  }
}'
    1. Check ‘blog’ type analyzer(kr_analyzer) on blogs’ index mappings
...   
 "mappings" : {
      "blog" : {
        "_all" : {
          "analyzer" : "kr_analyzer"
        },
...        
curl localhost:9200/blogs/_mappings?pretty

result:

{
  "blogs" : {
    "mappings" : {
      "blog" : {
        "_all" : {
          "analyzer" : "kr_analyzer"
        },
        "properties" : {
          "author" : {
            "properties" : {
              "_id" : {
                "type" : "text"
              },
              "email" : {
                "type" : "text"
              },
              "name" : {
                "type" : "text"
              }
            }
          },
          "comments" : {
            "properties" : {
              "__v" : {
                "type" : "double"
              },
              "author" : {
                "properties" : {
                  "_id" : {
                    "type" : "text"
                  },
                  "email" : {
                    "type" : "text"
                  },
                  "name" : {
                    "type" : "text"
                  }
                }
              },
              "content" : {
                "type" : "text"
              },
              "created_at" : {
                "type" : "date"
              },
              "updated_at" : {
                "type" : "date"
              }
            }
          },
          "content" : {
            "type" : "text"
          },
          "created_at" : {
            "type" : "date"
          },
          "files" : {
            "properties" : {
              "ctype" : {
                "type" : "text"
              },
              "name" : {
                "type" : "text"
              },
              "size" : {
                "type" : "text"
              },
              "uri" : {
                "type" : "text"
              }
            }
          },
          "summary" : {
            "type" : "text"
          },
          "title" : {
            "type" : "text"
          }
        }
      }
    }
  }
}

Elasticsearch Custom Analyzer applied to Node.js Mongoosastic search

  • blog.model.js
  • blog.controller.js: search function

blog.model.js

'use strict';
import Comment from './comment.model';
import Taggable from './taggable.model';

var mongoose = require('bluebird').promisifyAll(require('mongoose'));
var CommentSchema = Comment.schema;
var mongoosastic = require('bluebird').promisifyAll(require('mongoosastic'));

var BlogSchema = new mongoose.Schema({
  title: { type: String, required: true,es_indexed:true},
  photo_url: String,
  summary: {type:String, es_indexed:true},
  content: {type:String, es_indexed:true},
  published: Boolean,
  created_at: {type: Date, default: Date.now, es_indexed: true},
  updated_at: {type: Date, default: Date.now()},
  author: {
    _id: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
    name: String,
    email: String
  },
  comments: [CommentSchema],
  tags: {type: [String]},
  files: [{
    name: String,
    ctype: {type: String},
    size: String,
    uri: String
  }]
});

var validatePresenceOf = function(value) {
  return value && value.length;
};

BlogSchema.methods = {
  setTaggable(tags){
    this.removeTaggable();
    Taggable.addTags({type: 'Blog', taggable_id: this._id, tags: (tags || this.tags)});
  },
  removeTaggable(type, taggable_id){
    Taggable.removeTaggable(type || 'Blog', taggable_id || this._id);
  }
};

BlogSchema.plugin(mongoosastic);
var Blog = mongoose.model('Blog', BlogSchema);
Blog.createMapping({
  "settings": {
    "analysis": {
      "analyzer": {
        "kr_analyzer": {
          "type": "custom",
          "tokenizer": "kr_tokenizer",
          "filter": ["trim", "lowercase","english_stop", "en_snow", "kr_filter"]
        }
      },
      "filter": {
        "en_snow": {
          "type": "snowball",
          "language": "English"
        },
        "english_stop": {
          "type":       "stop",
          "stopwords":  "_english_"
        }
      }
    }
  },
  "mappings": {
    "blog": {
      "_all": {
        "analyzer": "kr_analyzer",
        "search_analyzer": "kr_analyzer"
      }
    }
  }
}, (err, mapping) => {
  if(err){
    console.log('error creating mapping (you can safely ignore this)');
    console.log(err);
  }else {
    console.log('mapping created!');
    console.log(mapping);
  }
});
export default Blog;

blog.controller.js: search function

import paginate from 'node-paginate-anything';
import Blog from './blog.model';

export function search(req, res, next){
  var clientLimit = req.query.clientLimit;
  var terms = req.params.terms;
  try {
    Blog.search({query_string: {query: terms}}, {size: 0, hydrate:true}, (err, results) => {
      if (err) {
        console.error(err);
        throw err;
      }
      console.log(results)
      if(results.hits.total === 0){
        return res.status(200).json([]);
      }
      var totalItems = results.hits.total;
      var maxRangeSize = clientLimit;
      var queryParams = paginate(req, res, totalItems, maxRangeSize);
      //console.log(queryParams);
      Blog.search({query_string: {query: terms}}, {
        from: queryParams.skip,
        size: queryParams.limit,
        sort: 'created_at:desc',
        hydrate: true,
        highlight: {
          "pre_tags": ["<em>"],
          "post_tags": ["</em>"],
          "fields": {
            "_all": {}
          }
        }
      }, (err, results) => {
        if (err) {
          console.error(err);
          throw err;
        }
        var blogs = [];
        results.hits.hits.forEach((hit) => {
          blogs.push(hit);
        });

        res.status(200).json(blogs);
      });
    });
  } catch(err) {
    console.error(err);
    res.status(500).json(err.message || err);
  }
}

Leave a Reply