[libclucy-clojure] 01/04: Imported Upstream version 0.4.0
Daigo Moriwaki
daigo at moszumanska.debian.org
Sat Jun 14 06:47:05 UTC 2014
This is an automated email from the git hooks/post-receive script.
daigo pushed a commit to branch master
in repository libclucy-clojure.
commit 668eaa46715a8d1ca7bf5bdeb81112a8280e5361
Author: Daigo Moriwaki <daigo at debian.org>
Date: Sat Jun 14 15:25:44 2014 +0900
Imported Upstream version 0.4.0
---
.gitignore | 8 ++--
.travis.yml | 8 ++++
README.md | 4 +-
project.clj | 27 ++++++-------
src/clucy/core.clj | 102 +++++++++++++++++++++++++++++------------------
test/clucy/test/core.clj | 19 +++++++--
6 files changed, 108 insertions(+), 60 deletions(-)
diff --git a/.gitignore b/.gitignore
index 2302003..eea145e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
-classes
-lib
+/classes
+/lib
+/target
clucy*.jar
pom.xml
-/.lein-failures
+pom.xml.asc
+.lein-failures
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..b1ddc59
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,8 @@
+language: clojure
+
+lein: lein2
+
+jdk:
+ - openjdk6
+ - openjdk7
+ - oraclejdk7
\ No newline at end of file
diff --git a/README.md b/README.md
index 5c514d2..d5adf76 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
Clucy
=====
+[](http://travis-ci.org/weavejester/clucy)
+
Clucy is a Clojure interface to [Lucene](http://lucene.apache.org/).
Installation
@@ -9,7 +11,7 @@ Installation
To install Clucy, add the following dependency to your `project.clj`
file:
- [clucy "0.3.0"]
+ [clucy "0.4.0"]
Usage
-----
diff --git a/project.clj b/project.clj
index 89bcbd0..ce4ed9d 100644
--- a/project.clj
+++ b/project.clj
@@ -1,16 +1,15 @@
-(defproject clucy "0.3.0"
+(defproject clucy "0.4.0"
:description "A Clojure interface to the Lucene search engine"
:url "http://github/weavejester/clucy"
- :dependencies [[org.clojure/clojure "1.3.0"]
- [org.apache.lucene/lucene-core "3.5.0"]
- [org.apache.lucene/lucene-highlighter "3.5.0"]]
- :dev-dependencies [[lein-multi "1.1.0"]]
- :multi-deps {"1.2-lucene2" [[org.clojure/clojure "1.2.1"]
- [org.apache.lucene/lucene-core "2.9.2"]
- [org.apache.lucene/lucene-highlighter "2.9.2"]]
- "1.3-lucene2" [[org.clojure/clojure "1.3.0"]
- [org.apache.lucene/lucene-core "2.9.2"]
- [org.apache.lucene/lucene-highlighter "2.9.2"]]
- "1.2-lucene3" [[org.clojure/clojure "1.2.1"]
- [org.apache.lucene/lucene-core "3.5.0"]
- [org.apache.lucene/lucene-highlighter "3.5.0"]]})
+ :dependencies [[org.clojure/clojure "1.4.0"]
+ [org.apache.lucene/lucene-core "4.2.0"]
+ [org.apache.lucene/lucene-queryparser "4.2.0"]
+ [org.apache.lucene/lucene-analyzers-common "4.2.0"]
+ [org.apache.lucene/lucene-highlighter "4.2.0"]]
+ :license {:name "Eclipse Public License"
+ :url "http://www.eclipse.org/legal/epl-v10.html"}
+ :profiles {:1.4 {:dependencies [[org.clojure/clojure "1.4.0"]]}
+ :1.5 {:dependencies [[org.clojure/clojure "1.5.0"]]}
+ :1.6 {:dependencies [[org.clojure/clojure "1.6.0-master-SNAPSHOT"]]}}
+ :codox {:src-dir-uri "http://github/weavejester/clucy/blob/master"
+ :src-linenum-anchor-prefix "L"})
diff --git a/src/clucy/core.clj b/src/clucy/core.clj
index aa75a0d..a08db80 100644
--- a/src/clucy/core.clj
+++ b/src/clucy/core.clj
@@ -1,21 +1,24 @@
(ns clucy.core
(:import (java.io StringReader File)
+ (org.apache.lucene.analysis Analyzer TokenStream)
(org.apache.lucene.analysis.standard StandardAnalyzer)
(org.apache.lucene.document Document Field Field$Index Field$Store)
- (org.apache.lucene.index IndexWriter IndexWriter$MaxFieldLength Term)
- (org.apache.lucene.queryParser QueryParser)
+ (org.apache.lucene.index IndexWriter IndexReader Term
+ IndexWriterConfig DirectoryReader FieldInfo)
+ (org.apache.lucene.queryparser.classic QueryParser)
(org.apache.lucene.search BooleanClause BooleanClause$Occur
- BooleanQuery IndexSearcher TermQuery)
+ BooleanQuery IndexSearcher Query ScoreDoc
+ Scorer TermQuery)
(org.apache.lucene.search.highlight Highlighter QueryScorer
SimpleHTMLFormatter)
- (org.apache.lucene.store NIOFSDirectory RAMDirectory)
- (org.apache.lucene.util Version)))
+ (org.apache.lucene.util Version AttributeSource)
+ (org.apache.lucene.store NIOFSDirectory RAMDirectory Directory)))
(def ^{:dynamic true} *version* Version/LUCENE_CURRENT)
(def ^{:dynamic true} *analyzer* (StandardAnalyzer. *version*))
;; To avoid a dependency on either contrib or 1.2+
-(defn as-str [x]
+(defn as-str ^String [x]
(if (keyword? x)
(name x)
(str x)))
@@ -30,15 +33,21 @@
(defn disk-index
"Create a new index in a directory on disk."
- [dir-path]
+ [^String dir-path]
(NIOFSDirectory. (File. dir-path)))
(defn- index-writer
"Create an IndexWriter."
+ ^IndexWriter
[index]
(IndexWriter. index
- *analyzer*
- IndexWriter$MaxFieldLength/UNLIMITED))
+ (IndexWriterConfig. *version* *analyzer*)))
+
+(defn- index-reader
+ "Create an IndexReader."
+ ^IndexReader
+ [index]
+ (DirectoryReader/open ^Directory index))
(defn- add-field
"Add a Field to a Document.
@@ -51,7 +60,7 @@
(add-field document key value {}))
([document key value meta-map]
- (.add document
+ (.add ^Document document
(Field. (as-str key) (as-str value)
(if (false? (:stored meta-map))
Field$Store/NO
@@ -96,7 +105,8 @@
[index & maps]
(with-open [writer (index-writer index)]
(doseq [m maps]
- (.addDocument writer (map->document m)))))
+ (.addDocument writer
+ (map->document m)))))
(defn delete
"Deletes hash-maps from the search index."
@@ -114,27 +124,28 @@
(defn- document->map
"Turn a Document object into a map."
- ([document score]
+ ([^Document document score]
(document->map document score (constantly nil)))
- ([document score highlighter]
- (let [m (into {} (for [f (.getFields document)]
+ ([^Document document score highlighter]
+ (let [m (into {} (for [^Field f (.getFields document)]
[(keyword (.name f)) (.stringValue f)]))
fragments (highlighter m) ; so that we can highlight :_content
m (dissoc m :_content)]
(with-meta
m
(-> (into {}
- (for [f (.getFields document)]
- [(keyword (.name f)) {:indexed (.isIndexed f)
- :stored (.isStored f)
- :tokenized (.isTokenized f)}]))
+ (for [^Field f (.getFields document)
+ :let [field-type (.fieldType f)]]
+ [(keyword (.name f)) {:indexed (.indexed field-type)
+ :stored (.stored field-type)
+ :tokenized (.tokenized field-type)}]))
(assoc :_fragments fragments :_score score)
(dissoc :_content))))))
(defn- make-highlighter
"Create a highlighter function which will take a map and return highlighted
fragments."
- [query searcher config]
+ [^Query query ^IndexSearcher searcher config]
(if config
(let [indexReader (.getIndexReader searcher)
scorer (QueryScorer. (.rewrite query indexReader))
@@ -148,34 +159,47 @@ fragments."
highlighter (Highlighter. (SimpleHTMLFormatter. pre post) scorer)]
(fn [m]
(let [str (field m)
- token-stream (.tokenStream *analyzer*
+ token-stream (.tokenStream ^Analyzer *analyzer*
(name field)
(StringReader. str))]
- (.getBestFragments highlighter
- token-stream
- str
- max-fragments
- separator))))
+ (.getBestFragments ^Highlighter highlighter
+ ^TokenStream token-stream
+ ^String str
+ (int max-fragments)
+ ^String separator))))
(constantly nil)))
(defn search
"Search the supplied index with a query string."
- [index query max-results & {:keys [highlight default-field]}]
+ [index query max-results
+ & {:keys [highlight default-field default-operator page results-per-page]
+ :or {page 0 results-per-page max-results}}]
(if (every? false? [default-field *content*])
(throw (Exception. "No default search field specified"))
- (let [default-field (or default-field :_content)]
- (with-open [searcher (IndexSearcher. index)]
- (let [parser (QueryParser. *version* (as-str default-field) *analyzer*)
- query (.parse parser query)
- hits (.search searcher query max-results)
- highlighter (make-highlighter query searcher highlight)]
- (doall
- (with-meta (for [hit (.scoreDocs hits)]
- (document->map (.doc searcher (.doc hit))
- (.score hit)
- highlighter))
- {:_total-hits (.totalHits hits)
- :_max-score (.getMaxScore hits)})))))))
+ (with-open [reader (index-reader index)]
+ (let [default-field (or default-field :_content)
+ searcher (IndexSearcher. reader)
+ parser (doto (QueryParser. *version*
+ (as-str default-field)
+ *analyzer*)
+ (.setDefaultOperator (case (or default-operator :or)
+ :and QueryParser/AND_OPERATOR
+ :or QueryParser/OR_OPERATOR)))
+ query (.parse parser query)
+ hits (.search searcher query (int max-results))
+ highlighter (make-highlighter query searcher highlight)
+ start (* page results-per-page)
+ end (min (+ start results-per-page) (.totalHits hits))]
+ (doall
+ (with-meta (for [hit (map (partial aget (.scoreDocs hits))
+ (range start end))]
+ (document->map (.doc ^IndexSearcher searcher
+ (.doc ^ScoreDoc hit))
+ (.score ^ScoreDoc hit)
+
+ highlighter))
+ {:_total-hits (.totalHits hits)
+ :_max-score (.getMaxScore hits)}))))))
(defn search-and-delete
"Search the supplied index with a query string and then delete all
diff --git a/test/clucy/test/core.clj b/test/clucy/test/core.clj
index c0f3658..07bc0a4 100644
--- a/test/clucy/test/core.clj
+++ b/test/clucy/test/core.clj
@@ -1,6 +1,7 @@
(ns clucy.test.core
(:use clucy.core
- clojure.test))
+ clojure.test
+ [clojure.set :only [intersection]]))
(def people [{:name "Miles" :age 36}
{:name "Emily" :age 0.3}
@@ -33,7 +34,10 @@
(testing "search fn"
(let [index (memory-index)]
(doseq [person people] (add index person))
- (is (== 1 (count (search index "name:miles" 10))))))
+ (is (== 1 (count (search index "name:miles" 10))))
+ (is (== 1 (count (search index "name:miles age:100" 10))))
+ (is (== 0 (count (search index "name:miles AND age:100" 10))))
+ (is (== 0 (count (search index "name:miles age:100" 10 :default-operator :and))))))
(testing "search-and-delete fn"
(let [index (memory-index)]
@@ -56,4 +60,13 @@
(is (true? (every? pos? (map (comp :_score meta) results))))
(is (= 2 (:_total-hits (meta results))))
(is (pos? (:_max-score (meta results))))
- (is (= (count people) (:_total-hits (meta (search index "*:*" 2))))))))
+ (is (= (count people) (:_total-hits (meta (search index "*:*" 2)))))))
+
+ (testing "pagination"
+ (let [index (memory-index)]
+ (doseq [person people] (add index person))
+ (is (== 3 (count (search index "m*" 10 :page 0 :results-per-page 3))))
+ (is (== 1 (count (search index "m*" 10 :page 1 :results-per-page 3))))
+ (is (empty? (intersection
+ (set (search index "m*" 10 :page 0 :results-per-page 3))
+ (set (search index "m*" 10 :page 1 :results-per-page 3))))))))
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libclucy-clojure.git
More information about the pkg-java-commits
mailing list