Skip to content

Commit

Permalink
Allow searching on multiple fields at once
Browse files Browse the repository at this point in the history
Also allows searching by version.

Examples:

$ lein search "id:clojure group:org.clojure version:1.6"
$ lein search "id:postgres version:7.4"
$ lein search "id:postgres version:'7.4'"
  • Loading branch information
trptcolin committed Mar 27, 2014
1 parent 1995275 commit 5e04894
Showing 1 changed file with 25 additions and 13 deletions.
38 changes: 25 additions & 13 deletions src/leiningen/search.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
[leiningen.core.main :as main]
[leiningen.core.project :as project]
[clj-http.client :as http])
(:import (org.apache.maven.index IteratorSearchRequest MAVEN NexusIndexer)
(:import (org.apache.lucene.search BooleanClause$Occur)
(org.apache.lucene.search BooleanQuery)
(org.apache.maven.index IteratorSearchRequest MAVEN NexusIndexer)
(org.apache.maven.index.context IndexingContext)
(org.apache.maven.index.creator JarFileContentsIndexCreator
MavenPluginArtifactInfoIndexCreator
Expand Down Expand Up @@ -138,7 +140,7 @@
(println)))

(def ^{:private true}
field-splitter-re #"^([a-z]+)(?:\:)(.+)")
multi-entry-splitter-re #"([a-z]+)(?:\:)('[^']+'|[^ ]+)")

(defn- lookup-lucene-field-for
[^String s]
Expand All @@ -155,25 +157,34 @@
"d" MAVEN/DESCRIPTION
"desc" MAVEN/DESCRIPTION
"description" MAVEN/DESCRIPTION
(throw (IllegalArgumentException. (format "search over the field %s is not supported; known fields: id, description (aliased as d), group (aliased as g)" s)))))
"v" MAVEN/VERSION
"version" MAVEN/VERSION
(throw (IllegalArgumentException. (format "search over the field %s is not supported; known fields: id, description (aliased as d), group (aliased as g), version (aliased as v)" s)))))

(defn- split-query
"Splits \"field:query\" into \"field\" and \"query\""
[^String s]
(let [[_ field query] (re-find field-splitter-re s)]
(defn- query-parts [^String s]
(for [[full-text field query] (or (re-seq multi-entry-splitter-re s)
[[s ""]])]
[(lookup-lucene-field-for field)
(or query s)]))
(or query full-text)]))

(defn- construct-query [[field q]]
(let [search-expression (UserInputSearchExpression. q)]
(.constructQuery indexer field search-expression)))

(defn search-repository [query contexts page]
(let [[field q] (split-query query)
search-expression (UserInputSearchExpression. q)
constructed-query (.constructQuery indexer field
search-expression)
(let [query-parts (query-parts query)
queries (map construct-query query-parts)
constructed-query (BooleanQuery.)
_ (doseq [q queries]
(.add constructed-query q BooleanClause$Occur/MUST))
request (doto (IteratorSearchRequest. constructed-query contexts)
(.setStart (* (dec page) page-size))
(.setCount page-size))]
(with-open [response (.searchIterator indexer request)]
(println (format "Searching over %s..." (.getDescription field)))
(let [search-fields (map (comp #(.getDescription %) first)
query-parts)]
(println (format "Searching over %s..."
(string/join ", " search-fields))))
(print-results response page))))

(defn ^:no-project-needed search
Expand All @@ -187,6 +198,7 @@ matches or do more advanced queries such as this:
$ lein search clojure
$ lein search description:crawl
$ lein search group:clojurewerkz
$ lein search \"id:clojure version:1.6\"
$ lein search \"Riak client\"
Also accepts a second parameter for fetching successive pages."
Expand Down

0 comments on commit 5e04894

Please sign in to comment.