Reputation: 5650
So I have some posts that get tagged, and I'd like users to be able to add tags, and then I'd like to be able to do a query and get an aggregated list of tags for particular posts. (Currently the behavior just returns a list of entities, each with a different :tags attribute.)
({:title "Straight edges ...",
:content "If you ever ... ",
:tags "folding", <<< +
:eid 1759}
{:title "Straight edges ...",
:content "If you ever ...",
:tags "art", <<< +
:eid 1759}
{:title "Straight edges ...",
:content "If you ever ... ",
:tags "scissor-less edges", <<< +
:eid 1759}
{:title "Straight edges ...",
:content "If you ever ... ",
:tags "snips", <<< +
:eid 1759}
{:title "Straight edges ...",
:content "If you ever ... ",
:tags "scissor-less edges", <<< ^ How to combine?
:eid 1759})
My query looks like
(defn get-post-by-eid [eid]
(->> (d/q '[:find ?title ?content ?tags ?eid
:in $ ?eid
:where
[?eid post/title ?title]
[?eid post/content ?content]
[?eid post/tag ?tags]] (d/db conn) eid)
(map (fn [[title content tags eid]]
{:title title
:content content
:tags tags
:eid eid}))
(sort-by :eid)))
The desired result is something like
({:title "Straight edges ...",
:content "If you ever ... ",
:tags "folding, art, scissor-less edges, snips", ;;combination
:eid 1759}
Any tips on how I can query for this, or how I can mash all the query results together? Thanks in advance
Upvotes: 2
Views: 253
Reputation: 91554
I'm personally fond of combining sort-by
partition-by
and merge-with
for things like this, though in this case since everything is the same between entries except the tags you can skip the merge step and just stick the correct :tags value into any arbitrary list entry (I chose the first)
user> (->>
'({:title "Straight edges ...",
:content "If you ever ... ",
:tags "folding",
:eid 1759}
{:title "Straight edges ...",
:content "If you ever ...",
:tags "art",
:eid 1759}
{:title "Straight edges ...",
:content "If you ever ... ",
:tags "scissor-less edges",
:eid 1759}
{:title "Straight edges ...",
:content "If you ever ... ",
:tags "snips",
:eid 1759}
{:title "other post edges ...",
:content "If you ever ... ",
:tags "example",
:eid 9999}
{:title "Straight edges ...",
:content "If you ever ... ",
:tags "scissor-less edges",
:eid 1759})
(sort-by :eid)
(partition-by :eid)
(map #(assoc (first %)
:tags (clojure.string/join ", " (map :tags %))))
pprint)
Which produces a sequence of posts with rolled up tags:
({:title
"Straight edges ...",
:content "If you ever ... ",
:tags "folding, art, scissor-less edges, snips, scissor-less edges",
:eid 1759}
{:title "other post edges ...",
:content "If you ever ... ",
:tags "example",
:eid 9999})
Upvotes: 3