Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/select distinct #383

Merged
merged 8 commits into from
Feb 14, 2023
Merged
10 changes: 9 additions & 1 deletion src/fluree/db/query/exec.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@

#?(:clj (set! *warn-on-reflection* true))

(defn remove-duplicates
[q result-ch]
(if (:select-distinct q)
(async/pipe result-ch
(async/chan 1 (distinct)))
result-ch))

(defn drop-offset
"Returns a channel containing the stream of solutions from `solution-ch` after
the `offset` specified by the supplied query. Returns the original
Expand Down Expand Up @@ -53,9 +60,10 @@
(group/combine q)
(having/filter q error-ch)
(order/arrange q)
(select/format db q error-ch)
(remove-duplicates q)
(drop-offset q)
(take-limit q)
(select/format db q error-ch)
(collect-results q))]
(async/alt!
error-ch ([e] e)
Expand Down
3 changes: 2 additions & 1 deletion src/fluree/db/query/exec/select.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@
[db q error-ch solution-ch]
(let [compact (->> q :context json-ld/compact-fn)
selectors (or (:select q)
(:select-one q))
(:select-one q)
(:select-distinct q))
iri-cache (volatile! {})
format-ch (chan)]
(async/pipeline-async 1
Expand Down
27 changes: 17 additions & 10 deletions src/fluree/db/query/fql/parse.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -361,17 +361,24 @@
[q db context]
(let [depth (or (:depth q) 0)
select-key (some (fn [k]
(and (contains? q k) k))
[:select :selectOne :select-one])
select (-> q
(get select-key)
(parse-select-clause db context depth))]
(when (contains? q k) k))
[:select :selectOne :select-one
:selectDistinct :select-distinct])
select (-> q
(get select-key)
(parse-select-clause db context depth))]
(case select-key
:select (assoc q :select select)
:select-one (assoc q :select-one select)
:selectOne (-> q
(dissoc :selectOne)
(assoc :select-one select)))))
(:select
:select-one
:select-distinct) (assoc q select-key select)

:selectOne (-> q
(dissoc :selectOne)
(assoc :select-one select))

:selectDistinct (-> q
(dissoc :selectDistinct)
(assoc :select-distinct select)))))

(defn ensure-vector
[x]
Expand Down
4 changes: 4 additions & 0 deletions src/fluree/db/query/fql/syntax.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@
[:collection [:sequential ::selector]]]
::selectOne ::select
::select-one ::selectOne
::select-distinct ::select
::selectDistinct ::select-distinct
::direction [:orn
[:asc [:fn asc?]]
[:desc [:fn desc?]]]
Expand Down Expand Up @@ -178,6 +180,8 @@
[:select {:optional true} ::select]
[:selectOne {:optional true} ::selectOne]
[:select-one {:optional true} ::select-one]
[:selectDistinct {:optional true} ::selectDistinct]
[:select-distinct {:optional true} ::select-distinct]
[:delete {:optional true} ::delete]
[:orderBy {:optional true} ::orderBy]
[:order-by {:optional true} ::order-by]
Expand Down
17 changes: 17 additions & 0 deletions test/fluree/db/query/fql_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,23 @@
:having (>= (avg ?favNums) 2)}))
"filters results according to the supplied having function code")))))

(deftest ^:integration select-distinct-test
(testing "Distinct queries"
(let [conn (test-utils/create-conn)
people (test-utils/load-people conn)
db (fluree/db people)
q '{:context {:ex "http://example.org/ns/"}
:select-distinct [?name ?email]
:where [[?s :schema/name ?name]
[?s :schema/email ?email]
[?s :ex/favNums ?favNum]]
:order-by ?favNum}]
(is (= [["Cam" "cam@example.org"]
["Brian" "brian@example.org"]
["Alice" "alice@example.org"]]
@(fluree/query db q))
"return results without repeated entries"))))

(deftest ^:integration values-test
(testing "Queries with pre-specified values"
(let [conn (test-utils/create-conn)
Expand Down