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
-
- Deleting ‘blogs’ index if exists
curl -XDELETE localhost:9200/blogs
-
- 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"
}
}
}
}'
-
- 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);
}
}