[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
 =====
 
+[![Build Status](https://secure.travis-ci.org/weavejester/clucy.png?branch=master)](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