Related Items / Stored Search

Permalink
Great CMS btw! Really liking Concrete5.

I'm building a support site with it, and not sure the best way to do this next part. I have a page, say explaining how to do X. What I want is a generated list of pages related to X. Amazon's "May I recommend" is another good example of what I want.

I played around with the Auto-Nav, but can't get the desired results. For example related information may be in another branch in the site-map so those pages won't show up.

One idea for a solution is to store a search, and display the top 5 search results. So as the site grows and evolves the search results will grow and evolve with it. I'd have to make a custom block for this I guess.

Any other ideas how I could do this?
-Owen

 
Fernandos replied on at Permalink Reply
Fernandos
There are many ways to calculate the similarity of two items, but for a straightforward method, take a look at the Jaccard Coefficient.

See here: http://en.wikipedia.org/wiki/Jaccard_index...

Which is: J(a,b) = intersection(a,b)/union(a,b)


So the most related item to a would be the item which results in the highest Jaccard Coefficient when paired with a.

To conclude, there are 3 different approaches I remember:
- deep structural analysis of an item
- intensive social behavior analysis around an item
- structural analysis of an item, paired with behavioral analysis around the item

I doubt you want to go 10steps deeper in complexity but if so I can try to help you.

It's about semantic realationships and about ai-algorithms or similarity algorithms.

Here are some start points for you:
http://www.w3.org/TR/daml+oil-walkthru/...
http://www.mindswap.org/
http://en.wikipedia.org/wiki/Semantic_Web#Web_3.0...
http://en.wikipedia.org/wiki/OMDoc...

This is overkill, but interesting:
http://en.wikipedia.org/wiki/DARPA_Agent_Markup_Language...

Short version of that article. DARPA made machines learn learning itself and use media of many databases that DARPA has access to and the internet to make that machines smarter..

If you still read you might also be interested that web3 ain't about html5 and css3, but about the semantic relationship and autonomous use of webservices by articial intelligence. Real machines like toasters, freezers, cellphones etc. would work offline+online and interchange relevant information to other trusted machines or a web-services to fullfill a task.

Edited: To reduce useless information.
ScottC replied on at Permalink Reply
ScottC
yeah basically the "easiest" way to do this is simply to provide a form wrapper around page creation which creates associated meta-data(whatever you want to provide search around) in addition to the actual page creation. You definitely have tags you want to search by, so then you can create the tags to associate with each search and go from there.

The select attributes are a very nice start, I haven't played around with them associated with collections(due to my current project being db and not collection based) but I think that would be a good start for you to accomplish.

All you really need is to pick say 10 keywords per article, grab collection IDs where that select attribute is related to the page/collection, throw the cIDs in an array(checking for mutiples), and you have a nice list of cIDs or if you want page objects do an each Page::getByID(cID) and you have a nice list of whatever you could possibly ever want to do...on your terms.

Probably like a 15 hour problem max.
owenmead replied on at Permalink Reply
ScottC,

Sounds like a good idea. If this current method doesn't work out in the real world I'll probably upgrade to your suggestion.

Took me just under 2 hours to do this. I created a "Preset Search" block. Essentially set a query for the block which will get run and the results shown. So if I'm on a page about Importing Google Contacts; it searches for they query I give it "Import Contacts" and voila related items.

Wonder if I should add this to the marketplace as a free block?

I bastardized the built in search block.

add.php / edit.php
<?php echo $form->label('storedQuery', 'Query');?>
<?php echo $form->text('storedQuery', array('style' => 'width: 320px'));?>
<?php echo $form->label('numItems', 'Num Items');?>
<?php echo $form->text('numItems', array('style' => 'width: 60px'));?>


controller.php
<?php
   class PresetSearchBlockController extends BlockController {
      var $pobj;
      protected $btDescription = "Display a list of results from a preset search query.";
      protected $btName = "Preset Search";
      protected $btTable = 'btPresetSearch';
      protected $btInterfaceWidth = "350";
      protected $btInterfaceHeight = "100";
      public $storedQuery;
      public $numItems;
      function view() {
         Loader::library('database_indexed_search');
         $ipl = new IndexedPageList();
         $ipl->filterByKeywords($this->storedQuery);
         $ipl->setItemsPerPage($this->numItems);


view.php
<?php  defined('C5_EXECUTE') or die(_("Access Denied.")); ?>
<?php  if (isset($error)) { ?>
   <?php echo $error?><br/><br/>
<?php  } ?>
<?php
if(count($results)==0){ ?>
   <p class="no_results"><?php echo t('No Items Found')?></p>
<?php  }else{ ?>
   <ul class="storedSearchResults">
   <?php
   $i = 1;
   foreach($results as $r) {
      $li_class = count($results) == $i++ ? 'movie last': 'movie';
      $currentPageBody = $r->getBodyContent();?>
      <li class="<?php echo $li_class; ?>"><a href="<?php echo DIR_REL?>/index.php?cID=<?php echo $r->getID()?>"><?php echo $r->getName()?></a></li>
cimdev replied on at Permalink Reply
Owen,
This looks handy... Is there a db.xml file or other files necessary in order to install via the Add Functionality page ? The more documentation the better.. I apologize, am new to Concrete..

Kevin
owenmead replied on at Permalink Reply
I've since left the company where I was working on this quite a number of months ago. So excuse me if I'm a bit rusty.

This leverages the built in search tools of Concrete5, so you don't need to add any tables etc. You should be able to just create a custom block with the above posted code, as long as you have searching setup and working.
Fernandos replied on at Permalink Reply
Fernandos
I know this is old, but I'd like to share the Slope One Algorithm with you:

# Daniel Lemire, Sean McGrath, Implementing a #Rating-Based Item-to-Item
#http://www.ondelette.com/lemire/abstracts/TRD01.html
CREATE TABLE rating (
    userID INT PRIMARY KEY,
    itemID INT NOT NULL,
    ratingValue INT NOT NULL,
    datetimestamp TIMESTAMP NOT NULL
);
CREATE TABLE dev (
  itemID1 int(11) NOT NULL default '0',
  itemID2 int(11) NOT NULL default '0',
  count int(11) NOT NULL default '0',
  sum int(11) NOT NULL default '0',
  PRIMARY KEY  (itemID1,itemID2)
);