Skip to content

Instantly share code, notes, and snippets.

@rintaun
Created September 30, 2018 17:25
Show Gist options
  • Select an option

  • Save rintaun/e8571ecba8c811646e3c27fa21bf95f5 to your computer and use it in GitHub Desktop.

Select an option

Save rintaun/e8571ecba8c811646e3c27fa21bf95f5 to your computer and use it in GitHub Desktop.
Prepared query for counting the subset of tags for stories with the given tags
class Story < Sequel::Model
STORY_COUNT_BY_TAGS =
select { [tag, count(tag)] }
.from(
select { unnest(tags).as(tag) }
.from(:stories)
.where(
Sequel
.pg_array(:tags)
.contains(Sequel.cast(:$filter, :'text[]').pg_array)
)
)
.exclude(tag: Sequel.cast(:$filter, 'text[]').pg_array.any)
.group(:tag)
.order(:count).reverse
.prepare(:all, :tag_counts)
# SELECT "tag", count("tag")
# FROM (
# SELECT unnest("tags") AS "tag"
# FROM "stories"
# WHERE ("tags" @> CAST($1 AS text[]))
# ) AS "t1"
# WHERE ("tag" != ANY(CAST($1 AS text[])))
# GROUP BY "tag"
# ORDER BY "count" DESC
def self.count_by_tags(*filter)
STORY_COUNT_BY_TAGS
.call(filter: filter)
.each_with_object({}) do |result, hash|
hash[result[:tag]] = result[:count]
end
end
end
@rintaun
Copy link
Copy Markdown
Author

rintaun commented Sep 30, 2018

The final exclude is intended to exclude tags in the specified filter from the results. However, the construction

WHERE ("tag" != ANY(CAST($1 AS text[])))

does not function as expected for the case of an empty filter array. It works as expected if the array contains any elements. On the other hand,

WHERE NOT ("tag" = ANY(CAST($1 AS text[])))

works as expected in both cases.

@rintaun
Copy link
Copy Markdown
Author

rintaun commented Sep 30, 2018

Incidentally, if there is a cleaner way to do the where and exclude calls, I'm all ears :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment