≡

wincent.dev

  • Products
  • Blog
  • Wiki
  • Issues
You are viewing an historical archive of past issues. Please report new issues to the appropriate project issue tracker on GitHub.
Home » Issues » Feature request #1209

Feature request #1209: Scope refinement while navigating the tag cloud

Kind feature request
Product wincent.dev
When Created 2009-01-26T15:56:40Z, updated 2009-02-03T05:42:47Z
Status closed
Reporter Greg Hurrell
Tags no tags

Description

Sorry about the abstruse summary line, but the way things currently work is this:

You click on a tag name, say "nginx" and are taken to a list of all items with that tag.

If you want to narrow your search to, say, items tagged with "nginx" and "updates", then you have to actually do a tag search and type "nginx updates".

It would be really neat if you could instead do the following:

Click on the tag name, "nginx", and see a list of all items with that tag (just as before).

However, in addition, you'd also see a list of other tags that you can click on to refine your search. In the case of the "nginx" example the other tags would be "updates" and "log.rotation", because those are the other tags that you can find on articles tagged with "nginx".

I am not sure if all this would result in an absolutely hideous database query, but it would certainly be a really nice ui thing.

If the query turns out to be too horrid, the least we can do is provide a way for a user to click on the cloud (without worrying about filtering things down to only the tags "updates" and "log.rotation").

Comments

  1. Greg Hurrell 2009-01-26T15:56:51Z

    Status changed:

    • From: New
    • To: Open
  2. Greg Hurrell 2009-01-28T05:53:51Z

    Let's start with a self CROSS JOIN (produces exponential growth of records; ie. if there are 1,000 taggings you'll get 1,000,000 rows back):

    SELECT * FROM taggings AS t1 JOIN taggings AS t2;

    Adding a WHERE clause to reduce the number of returned results:

    SELECT * FROM taggings AS t1 JOIN taggings AS t2 WHERE t1.tag_id = 38;

    To see the groupings a little more clearly:

    SELECT * FROM taggings AS t1 JOIN taggings AS t2 WHERE t1.tag_id = 38 ORDER BY t1.id;

    So just say there were 54 items with tag 38, you'd now get 54 x 1,000 rows in the result (54,000).

    SELECT * FROM taggings AS t1
    JOIN taggings AS t2
    WHERE t1.tag_id = 38 AND t1.taggable_id = t2.taggable_id AND t1.taggable_type = t2.taggable_type;

    This yields a big reduction in the returned result size.

    SELECT * FROM taggings AS t1
    JOIN taggings AS t2
    WHERE t1.tag_id = 38 AND t1.taggable_id = t2.taggable_id AND t1.taggable_type = t2.taggable_type
    GROUP BY t2.tag_id;

    And another reduction in result size.

    Now let's just get the column we're interested in:

    SELECT t2.tag_id
    FROM taggings AS t1
    JOIN taggings AS t2
    WHERE t1.tag_id = 38 AND t1.taggable_id = t2.taggable_id AND t1.taggable_type = t2.taggable_type
    GROUP BY t2.tag_id;

    Now let's JOIN the tags table at the same time so that we can get the tag names at the same time:

    SELECT t2.tag_id, tags.name
    FROM tags
    JOIN taggings AS t1
    JOIN taggings AS t2
    WHERE t1.tag_id = 38
    AND t1.taggable_id = t2.taggable_id
    AND t1.taggable_type = t2.taggable_type
    AND tags.id = t2.tag_id
    GROUP BY t2.tag_id;

    Not sure if this is right, but it produces the expected results on my small test case with only one tag. Will need to think about how this could be extending to handle multiple tags.

  3. Greg Hurrell 2009-01-28T06:28:23Z

    "Drilling down" gets a bit ugly.

    It's not enough to just do a t1.tag_id = 38 OR t1.tag_id = 40, nor a t1.tag_id IN (38, 40) because those won't actually narrow down the scope and the exact same results will be returned.

    Likewise t1.tag_id = 38 AND t1.tag_id = 40 won't work for obvious reasons.

    Basically, we need to do one more self-JOIN for each level that we wish to drill down. Evidently it will make sense to impose a limit on the number of joins we'll do although in practical terms most items have only 1 or 2 tags on them and it's hard to imagine drilling down more than 5 levels (I think the most heavily tagged item I have right now probably only has 3 or 4 tags on it).

    Here's an example with one additional level of drilling:

    SELECT t3.tag_id
    FROM taggings AS t1
    JOIN taggings AS t2
    JOIN taggings AS t3
    WHERE t1.tag_id = 38
    AND t2.tag_id = 40
    AND t1.taggable_id = t2.taggable_id
    AND t1.taggable_type = t2.taggable_type
    AND t3.taggable_id = t1.taggable_id
    AND t3.taggable_type = t1.taggable_type
    GROUP BY t3.tag_id;

    The same with the tags tabled JOIN-ed in so as to fetch the tag name at the same time:

    SELECT t3.tag_id, tags.name
    FROM tags, taggings AS t1
    JOIN taggings AS t2
    JOIN taggings AS t3
    WHERE t1.tag_id = 38
    AND t2.tag_id = 40
    AND t1.taggable_id = t2.taggable_id
    AND t1.taggable_type = t2.taggable_type
    AND t3.taggable_id = t1.taggable_id
    AND t3.taggable_type = t1.taggable_type
    AND tags.id = t3.tag_id
    GROUP BY t3.tag_id;

    And while we're at it we should probably exclude the passed in tags from the results list:

     SELECT t3.tag_id, tags.name
    FROM tags, taggings AS t1
    JOIN taggings AS t2
    JOIN taggings AS t3
    WHERE t1.tag_id = 38
    AND t2.tag_id = 40
    AND t1.taggable_id = t2.taggable_id
    AND t1.taggable_type = t2.taggable_type
    AND t3.taggable_id = t1.taggable_id
    AND t3.taggable_type = t1.taggable_type
    AND tags.id = t3.tag_id
    AND t3.tag_id NOT IN (38, 40)
    GROUP BY t3.tag_id;
  4. Greg Hurrell 2009-01-28T06:39:58Z

    For the purposes of illustration, here's the "first level" example again, this time with the passed-i tag excluded and including the "tagging count":

    SELECT t2.tag_id, tags.name, tags.taggings_count
    FROM tags
    JOIN taggings AS t1
    JOIN taggings AS t2
    WHERE t1.tag_id = 38
    AND t1.taggable_id = t2.taggable_id
    AND t1.taggable_type = t2.taggable_type
    AND tags.id = t2.tag_id
    AND t2.tag_id NOT IN (38)
    GROUP BY t2.tag_id;
  5. Greg Hurrell 2009-01-30T15:40:53Z

    Ok, this is now implemented and I'm reasonably happy with the result. Will be included in the next deployment.

  6. Greg Hurrell 2009-02-03T05:42:47Z

    Status changed:

    • From: Open
    • To: Closed
Add a comment

Comments are now closed for this issue.

  • contact
  • legal

Menu

  • Blog
  • Wiki
  • Issues
  • Snippets