Elasticsearch2.3.4分词插件开发

0. Elasticsearch的版本是2.3.4 首先你得有自己的一Analyzer和Tokenizer,可以参考前面的一篇文章 1. pom.xml 使用maven来构建项目,需要包含elasticsearch的依赖,否则编译不了 <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>2.3.4</version> <scope>provided</scope> </dependency> 然后es的plugin需要一个描述文件plugin-descriptor.properties,把这个文件放在src/main/resources这个目录,打包后安装到es里面就会出现在插件目录下了。这个文件需要写入下面的内容: description=${project.description} version=${project.version} name=${elasticsearch.plugin.name} site=${elasticsearch.plugin.site} jvm=${elasticsearch.plugin.jvm} classname=${elasticsearch.plugin.classname} java.version=${elasticsearch.plugin.java.version} elasticsearch.version=${elasticsearch.version} 这些才使用了maven在pom.xml定义的内容,直接定义在pom.xml的根路径下: <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <elasticsearch.plugin.name>elasticsearch-analysis-demo</elasticsearch.plugin.name> <elasticsearch.plugin.site>false</elasticsearch.plugin.site> <elasticsearch.plugin.jvm>true</elasticsearch.plugin.jvm> <elasticsearch.plugin.java.version>1.8</elasticsearch.plugin.java.version> <elasticsearch.version>2.3.4</elasticsearch.version> <elasticsearch.plugin.classname>org.elasticsearch.plugin.AnalysisDemoPlugin</elasticsearch.plugin.classname> </properties> 最重要的就是plugin-descriptor.properties里面的classname,也就是pom.xml定义的elasticsearch.plugin.classname节点里面的类名,这个类就是es加载plugin的入口。 2. 继承Plugin 现在来看Java代码,分词插件入口类需要继承org.elasticsearch.plugins.Plugin类,并实现三个方法: public String name() 返回插件名字 public String description 返回插件的描述 public void onModule(AnalysisModule model) 可以使用model这个AnalysisModule对象添加自定义的分词器 上代码: package org.elasticsearch.plugin; import com.lexiscn.elasticsearch.hylanda.HylandaAnalysisBinderProcessor; import org.elasticsearch.index.analysis.AnalysisModule; import org.elasticsearch.plugins.Plugin; public class AnalysisDemoPlugin extends Plugin { public static String PLUGIN_NAME = "elasticsearch-analysis-demo"; @Override public String name() { return PLUGIN_NAME; } @Override public String description() { return PLUGIN_NAME; } public void onModule(AnalysisModule model) { model.addProcessor(new HylandaAnalysisBinderProcessor()); } } 在model.addProcessor这个方法调用的时候,需要一个org.elasticsearch.index.analysis.AnalysisModule.AnalysisBinderProcessor对象。所以还需要实现一个继承处AnalysisBinderProcessor的类: ...

December 16, 2016

spacemacs配置figwheel环境

0. … clojure和clojurescript不像ruby on rails和django那样all in one的模式,只需要很少的配置就可以建立项目开始开发。clojure系的东西都是library,什么用着顺手就把什么加进来,然后稍做配置再使用。这跟emacs一样,完全私人定制,每个人都有自己的喜欢的extension,这应该是lisp系的习惯吧。所以在使用lisp系的东西的时候没有什么框架能一桶江湖。不过在clojurescript的开发当中figwheel还是少不了的,代码热加载功能太赞了,边写代码边看效果,不需要刷新浏览器,这就是传说的living coding。另外使用集成的IDE工具后,所有东西都有提示,敲两个字母就自动补全了,对于学习一门语言来说的确不是什么好事。闲话不多说,下面来配置一下livind coding的环境,使用spacemacs加上cider,info-clojure两个扩展。 了解更多figwheel请查看其github 1. 配置emacs 在spacemacs的配置文件.spacemacs的dotspacemacs-configuration-layers添加clojure dotspacemacs-configuration-layers '(clojure) 另外还需要inf-clojure,由于这个扩展不在spacemacs的layer列表里面,需要另外添加,在dotspacemacs-additional-packages添加即可 dotspacemacs-additional-packages '(inf-clojure) 重启spacemacs或者按SPC-f-e-R执行dotspacemacs/sync-configuration-layers 然后还需要添加一个个启动figwheel的函数,在.spacemacs后面添加下面的函数 (defun figwheel-repl () (interactive) (run-clojure "lein figwheel")) 在后面按c-x c-e执行上面函数的定义 2. 建立项目,修改project.clj 现在新建一个项目叫hello lein new app hello 修改project.clj为如下内容 (defproject hello "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.8.0"]] :plugins [[lein-figwheel "0.5.6"]] ;(1) :main ^:skip-aot hello.core :target-path "target/%s" ;;(2) :cljsbuild {:builds [{:id "dev" :source-paths ["src/cljs"] :figwheel true :compiler {:main "hello.core" :asset-path "js/out" :output-to "resources/public/js/app.js" :output-dir "resources/public/js/out"}}]} :profiles {:uberjar {:aot :all}}) 添加了两处: (1) 添加figwheel的支持 (2) 添加cljsbuild配置,这里需要注意的就是:figwheel true这一行,这是在编译的js文件里面添加figwheel的支持。还有:asset-path "js/out"这一行,不然加载google closure library会找不到对应的路径。 ...

September 1, 2016

从virtualbox创建vagrant box

有的时候vagrant官网提供的boxes可能并不是想要的,有些包含了太多东西,有些box又没有需要的。如果你的开发团队需要这样的一个box,那么你就应该自己动手创建一个。其实创建的过程挺简单的,只要每个步骤操作正确。 Follow下面步骤: 1、安装vagrant 2、安装virtualbox 3、在virtualbox创建一个linux (centos),假设名字叫centos 4、创建好centos后,还需要安装virtualbox的guest增强插件。安装之前需要在centos安装一些必须的工具: # yum install kernel-devel gcc perl # ln -s /usr/src/kernels/2.6.18-164.15.1.el5-i686 /usr/src/linux 上面第二行请把版本号换成你自己安装的centos的内核版本号,你可以通过uname -a查看,或者直接到/user/src/kernels目录查看即可 5、还需要创建一个vagrant账号,密码也是vagrant。注意请把root密码也设置成vagrant # groupadd vagrant # useradd -g vagrant vagrant # passwd vagrant 另外还需要设置sudo,因为vagrant默认会使用vagrant账号挂载工作目录到/vagrant。还需要设置tty,用root账号输入visudo,修改centos里面的/etc/sudoers注释下面两行 #Defaults requiretty #Defaults !visiblepw 添加下面一行到root ALL=(ALL) ALL下面 vagrant ALL=(ALL) ALL 6、检查guest******.iso是否加载,如果没有加载的话,请添加一个光驱,并且加载这个iso文件,一般这个iso文件在virtualbox的安装目录可以找到 7、连接上终端,输入下面的命令: mount /dev/cdrom /media/cdrom cd /media/cdrom ./VBoxLinuxAdditions.run 如果没有error说明安装成功,如果有关于X的错误,有可能是你没有安装X环境,如果只是使用命令行,这个也不用管 8、打包 vagrant package --base centos --output centos.box vagrant package就是vagrant用来打包的命令,--base指定你创建的虚拟机的名字,后面--output指定导出的box的位置和名字 9、打好包后,自己可以建立一个新的环境测试一下: vagrant box add base centos.box cd your vagrant workspace dir vagrant init base 10、这里要注意的一点是,由于没有找到使用publickey登录的方式,所以必须要在Vagrantfile的最后添加用户名和密码登录 ...

August 24, 2016

Scala学习笔记之正则表达式

QQ: 380800878, 微信: kittenll 如果还不熟悉正则表达式的可以先查看正则表达式30分钟入门教程,非常经典的入门教程。 Scala提供的正则表达式功能是通过类Regex来实现,函数签名为: Regex(regex: String, groupNames: String*) 第一个参数为正则表达式的字符串,后面是可变参数列表,是给regex里面的分组起一个名字。Scala的正则表达式的功能非常强大,这要得益于Scala本身特别的设计,尤其是pattern match,是其他编程语言很难超越的。 先来看第一个例子,匹配小写英文字母(如下代码中单独一行的=>表示接下来是结果): import scala.util.matching.Regex val str = "abc" val regex = new Regex("[a-z]+") println(regex.findAllIn(str).toList) => List(abc) 可以结果看到是一个元素的的List,匹配到字符串abc。如果要匹配到大写和小写,正则表达式需要修改成[a-zA-Z],还有另外一个办法就是为正则表达式添加选项,让[a-z]可以直接匹配到大写和小写字母,正则表达式就需要写成(?i)[a-z]+ import scala.util.matching.Regex val str = "abcEFGhijk" val regex = new Regex("(?i)[a-z]+") println(regex.findAllIn(str).toList) => List(abcEFGhijk) 所以在Scala添加选项的正确姿势就是在正则表达式的前面用使用括号问号+选项字母,这与PHP的正则完全不同,PHP使用如下的方式,使用相同的字符来做开头和结尾,这里就是/,其实在PHP里面使用%, |这些字符也是完全可以的,然后在后面的分割符后面加上选项字母 /[a-z]+/i 匹配简单的电话号码: import scala.util.matching.Regex val str = "13907461234" val regex = new Regex("""^1[358]\d{9}$""") println(regex.findAllIn(str).toList) => List(13907461234) 这里使用了"""raw string,三个双引号括起来的内容不需要做转义,正则表达式本身就比较难看,如果再加上转义就更难于阅读和理解。 匹配简单的电子邮件: val str = "email: abc@xyz.com" val regex = new Regex("""(?i)[a-z0-9._-]+@[a-z0-9._-]+(\.[a-z0-9._-]+)+""") println(regex.findAllIn(str).toList) => List(abc@xyz.com) Scala的正则表达式还有一个非常有用的功能,那就是模式匹配(pattern match),不仅可以查找所有匹配的的字符串,还可以直接提取分组的内容,请看下面api手册的例子: val date = """(\d\d\d\d)-(\d\d)-(\d\d)""".r //可以直接使用.r生成一个Regex对象 "2004-01-20" match { case date(year, month, day) => s"$year was a good year for PLs." } => 2004 was a good year for PLs. 可以看到上面的例子直接把年份的分组提取了出来,month, day同样也可以提取出来。 ...

August 23, 2016

ClojureScript学习笔记一(Hello World与REPL)

学习一门编程语言就像新出来的婴儿一样,一个裸体可以看清全部。学习编程语言也是一样的,一开始不可以使用任何一个工具。 ClojureScript继承了Clojure简单和富有表现力的语法,编译后的代码可以运行在浏览器和Node.js上面。 编写hello world程序。新建一个目录cljs_first_project,然后还需要建立存放源代码的目录。下载编译器{:target="_blank"},目录结构如下: cljs_first_project |- build.clj |- cljs.jar |- src |- cljs_first_project |- core.cljs 在core.cljs写入如下内容: (ns cljs-first-project.core) (js/alert "Hello world!") 这段代码定义一个命名空间,然后是一个javascript里面的alert弹出框。另外还需要写一个clojure文件来对源代码进行编译,在根目录下新建一个build.clj文件,内容如下: (require 'cljs.build.api) (cljs.build.api/build "src" {:output-to "out/main.js"}) 包含cljs.build.api命名空间,然后调整build函数,此函数接受两个参数,第一个是ClojureScript源代码目录,第二个是是一个map数据结果,这里指定了输出编译后的js的路径。现在使用前面下载的编译器进行编译: Windows下编译 java -cp "cljs.jar;src" clojure.main build.clj *nix下编译 java -cp cljs.jar:src clojure.main build.clj 编译完成后会在out目录生成main.js,同时还有其他一些目录。要运行main.js还需要一个greet.html,内容如下: <html> <body> <script type="text/javascript" src="out/goog/base.js"></script> <script type="text/javascript" src="out/main.js"></script> <script type="text/javascript"> goog.require("cljs_first_project.core") </script> </body> </html> 用浏览器打开greet.html就可以看到alert框了。第一个ClojureScript编写编译完成! 再来一点高级功能,把goog/base.js依赖从html去掉,把goog.require("cljs_first_project")也从html里面去掉,只需要包含main.js就可以让程序跑起来。只需要对build.clj修改一下,内容修改如下: (require 'cljs.build.api) (cljs.build.api/build "src" {:main 'cljs-first-project.core :output-to "out/main.js"}) greet.html的内容如下: ...

August 22, 2016

Webpack之Hello World

QQ: 380800878, 微信: kittenll 最近自己在做一些项目的时候使用Restful和react来做到前后端分离,感受到开发效率的成倍提升,故在此分享一下前端使用webpack作为前端的构建工具。 Webpack是一个前端资源加载,编译,打包工具,可以把多个分散的功能模块javascript, css打包压缩到一个模块当中;合并图片。Webpack使用使用各种的loader来加载编译对应的资源,在网上也有非常多的loader。 0、安装 全局安装: npm install webpack -g 还有一个开发者工具,此工具非常实用,后面介绍: npm install webpack-dev-server -g 也可以使用本地模式随源码一起发行: npm init npm install webpack --save-dev npm install webpack-dev-server --save-dev 随源码一起发行的好处就是不需要别人也强制全局安装,别人拿到源码后直接npm update后即可使用 1、简单使用 在介绍使用配置文件之前,先来看一下官方给出的最简单的编译例子: 新建一个目录hello,进行到hello目录,新建一个javascript文件entry.js,内容如下: document.write("It works."); 然后新建一个index.html文件,内容如下: <html> <head> <meta charset="utf-8"> </head> <body> <script type="text/javascript" src="bundle.js" charset="utf-8"></script> </body> </html> 编译entry.js到bundle.js: webpack ./entry.js bundle.js 如果正常编译通过,你会看到如下的输出(这是我自己的输出,你的输出可能会不太一样): Hash: a41c6217554e666594cb Version: webpack 1.13.1 Time: 67ms Asset Size Chunks Chunk Names bundle.js 1.42 kB 0 [emitted] main [0] ./entry.js 29 bytes {0} [built] 使用浏览器打开index.html,你将会看到网页上呈现It works. ...

August 6, 2016

spark连接mysql

QQ: 380800878, 微信: kittenll 一、下到驱动 官网载mysql的java驱动包放到spark根目录。启动: SPARK_CLASSPATH=mysql-connector-java-x.x.x-bin.jar ./bin/spark-shell 二、连接mysql val df = sqlContext.load("jdbc", Map("url" -> "jdbc:mysql://localhost:3306/newlaw?user=root&password=", "dbtable" -> "tax")) df.count() 这里得到的df是一个DataFrame对象,可以通过这个对象选取表数据,map, reduce等等操作。

April 20, 2016

使用Clojure开发Web入门系列(三)

在使用Clojure开发Web入门系列(二)的最后做了一个动态输出hello+url参数的一个小demo,如果有很多这样的需求,不同的url调用不同的处理函数,那么就得在调用cond的地方写上很多条件,或者再写上另外一个函数专门处理这些条件,这就是web后端开发的路由组件。 Clojure方便的一点就在此,对于这个功能已经有一个非常强大而实用的类库来处理了,那就是compojure,这就是一个强大的Ring/Clojure路由处理库。 零、添加依赖 打开项目根目录下面的project.clj,在dependencies里面添加compojure的依赖[compojure "1.6.1"] 然后运行lein deps下载依赖包。 一、修改代码 修改core.clj,最后看起来像下面这样 (ns learnweb.core (:require [ring.adapter.jetty :refer [run-jetty]] [compojure.core :refer [defroutes GET]] ; (1) [compojure.route :refer [not-found]]) ; (2) (:gen-class)) (defroutes app (GET "/" [] "<h1>Hello world!</h1>") (GET "/hello/:name" [name] (str "Hello " name)) (not-found "<h1>Page not found</h1>")) ; (3) (defn -main "I don't do a whole lot ... yet." [& args] (run-jetty app {:port 3000})) ; (4) 相比之前的简洁不少。 (1) 引入宏defroutes和GET。defroutes定义路由列表。GET定义一条路由规则,说明此条规则只处理http的get请求(其他的有post, head, put, delete, option,详细内容请参考rfc2616 Method Definitions)。 ...

March 14, 2016

我来学Kotlin-起步之基础语法

零、咱们先来看看Kotlin是啥语言。 JetBrains在2016年2月15日Kotlin 1.0发布,这意味着Kotlin经过几年的发展已经稳定而且可以在生产环境使用。再来看一下其他人: 如何评价 Kotlin 语言 Android开发时你遇到过什么相见恨晚的工具或网站 Kotlin, the Swift of Android Using Project Kotlin for Android 使用Kotlin进行Android开发 在网搜索一下就会发现已经有很多人在研究Kotlin并且使用其来开发Android,Android Studio原生就内置了Kotlin的工具和插件,可以方便的使用Kotlin开发Android。个人认为Kotlin没有Java那么多的历史包袱,而且写起来也没有Java那么的繁琐,但是又可以跟Java无缝结合,可以完全使用现在的各种库;相比Scala又简单不少。应该在JVM平台上可以发展得不错。我来学系列记录我自己学习的过程,同时希望可以能跟猿猴们一起探讨开发。下面的内容基本上是照着官方的文档来写,一来自己学习,二来跟大家一起讨论。 一、快速浏览语法 包定义 这个跟Java没有多少区别,在文件的最上面定义包的名字。如果需要引用其他包的内容,紧接着包定义的下面引入: package my.demo import java.util.* // ... 在Kotlin里面包的名字不一定要跟文件路径一致,一个源代码文件可以定义任意的包名。 定义函数 跟Java不同的是,在Kotlin里面可以定义单独的函数,而Java的函数必须属于某个类。下面是一个求和函数,把两个Int类型的变量相加,返回相加后的结果: fun sum(a: Int, b: Int): Int { return a + b } 还可以使用表达式的方式和类型推导来把上面的代码写得更加简洁: fun sum(a: Int, b: Int) = a + b 函数可以返回一个代表无值的值Unit,这有点像Java里面的void,但是跟void的意思大不相同。Unit类型表示一个值,但是这个值里面什么都没有: fun printSum(a: Int, b: Int): Unit { println("sum of $a and $b is ${a + b}") } 如果函数没有返回值,返回值缺省就是Unit ...

March 12, 2016

Clojure快速排序

QQ: 380800878, 微信: kittenll 看过Haskell的快速排序之后,真的是被折服了,简洁明了。现在用Clojure也来写一个快排,同样也是相当的简单。 (defn quick-sort [coll] (if (empty? coll) [] (let [[first & r] coll] (concat (quick-sort (filter #(< % first) r)) [first] (quick-sort (filter #(>= % first) r)))))) 算法的定义:排过序的 List 就是令所有小于等于头部的元素在先(它们已经排过了序), 后跟大于头部的元素(它们同样已经排过了序)。

March 9, 2016