Created
September 25, 2010 00:22
-
-
Save apage43/596292 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns sector | |
(:require [clj-http.client :as http]) | |
(:use [clojure.contrib.json])) | |
(def couch "http://127.0.0.1:5984/") | |
(def db (str couch "tagged/")) | |
(def view (str db "_design/merge/_view/tags")) | |
;;Just using rqc to record how many rqs are made. | |
(def rqc (agent 0)) | |
(defn jget [url opts] | |
(send rqc inc) | |
(read-json (:body (http/get url opts)))) | |
(defn getrows [url tag sid limit] | |
(jget url {:query-params | |
{"startkey" (json-str tag) | |
"startkey_docid" sid | |
"endkey" (json-str tag) | |
"limit" limit}})) | |
(defn further [a b] | |
(if (or (nil? b) (nil? a)) nil | |
(if (> (.compareTo a b) 0) a b))) | |
;; Usage: | |
;; (intersect-seq "http://127.0.0.1:5984/tagged/_design/merge/_view/tags" "cat" "dog") | |
;; returns a LAZY SEQUENCE OF docids of all docs tagged "cat" and "dog". | |
;; This means you can do | |
;; (take 5 (intersect-seq view "cat" "dog")) to retrieve up to 5 docs tagged "cat" and "dog" | |
;; and no more db requests than necessary will be made to retrieve that amount. | |
;; Works with any amount of tags: (intersect-seq view "cat" "dog" "snow") | |
;; Check timing and request count: | |
;; (binding [rqc (agent 0)] [(time (doall (intersect-seq view "chicken" "dog"))) @rqc]) | |
(defn intersect-seq [view & tags] | |
(let [curf (fn [skey self] | |
(let [curs (map #(getrows view % skey 2) tags) | |
counts (map #(count (:rows %)) curs) | |
ids (map #(if (> (count (:rows %1)) 0) (:id (first (:rows %1))) nil) curs) | |
match (apply = ids) | |
lst (reduce further ids)] | |
(if (< (apply min counts) 2) | |
(if match (list (first ids)) nil) | |
(lazy-cat (if match (list (first ids)) nil) | |
(self (if match | |
(reduce further (map #(:id (second (:rows %))) curs)) | |
lst) self)))))] (curf nil curf))) | |
;; Insert amt test docs tagged with tags: | |
;; (addtest db ["cat" "dog"] 5) | |
;; (addtest db ["cat"] 10000) | |
(defn addtest [db tags amt] | |
(http/post (str db "_bulk_docs") | |
{:body (json-str {:docs (map (fn [i] {:_id i :tags tags}) | |
(:uuids (jget (str couch "_uuids?count=" amt) nil)))}) | |
:content-type :json}) | |
nil) | |
;;I use this to upload my ddoc | |
(defn insert-file [db file] | |
(let [txt (slurp file) | |
json (read-json txt) | |
id (:_id json)] | |
(http/put (str db id) | |
{:body txt :content-type :json :basic-auth ["aaron" "aaron"]}))) | |
;;file: merge.json | |
;; { | |
;; "_id": "_design/merge", | |
;; "views": { | |
;; "tags": { | |
;; "map": "function(doc){for(var i in doc.tags) {emit(doc.tags[i], null);}}" | |
;; } | |
;; } | |
;; } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment