﻿<?xml version='1.0' encoding='UTF-8'?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>InstantASP Community Forums / Old Forums / InstantForum.NET 4.x / Suggestions &amp; Requests  / New full-text search queries / Latest Posts</title><generator>InstantForum.NET v4.1.4</generator><description>InstantASP Community Forums</description><link>http://community.instantasp.co.uk/</link><webMaster>sales@instantasp.co.uk</webMaster><lastBuildDate>Fri, 09 Jan 2009 03:48:27 GMT</lastBuildDate><ttl>20</ttl><item><title>RE: New full-text search queries</title><link>http://community.instantasp.co.uk/Topic10211-51-1.aspx</link><description>YGM</description><pubDate>Wed, 01 Mar 2006 11:05:53 GMT</pubDate><dc:creator>Drew Black</dc:creator></item><item><title>RE: New full-text search queries</title><link>http://community.instantasp.co.uk/Topic10211-51-1.aspx</link><description>Hi Drew,&lt;/P&gt;&lt;P&gt;Hope your well. Many thanks for sharing your code and taking time to look at this. &lt;/P&gt;&lt;P&gt;We will certainly investigate this for future versions. I'm particularly interested in the performance gains you've managed with your method. &lt;/P&gt;&lt;P&gt;Would it be possible for you to send your code via private message or over MSN to &lt;a target="_blank" href="mailto:sales@instantasp.co.uk"&gt;sales@instantasp.co.uk&lt;/A&gt;  I'd certainly like to investigate and test further. &lt;/P&gt;&lt;P&gt;If everything works well and we don't have issues with user defined functions within shared hosting environments we'll certainly look at using this method in future versions. I doubt this will be in place for v4.1.4 as it will require some testing. Of course if we were to use your method we will of reward you some how for your suggestion ;)&lt;/P&gt;&lt;P&gt;Please add me to your MSN. I look forward to testing and discussing this further :)</description><pubDate>Wed, 01 Mar 2006 08:00:16 GMT</pubDate><dc:creator>Ryan Healey</dc:creator></item><item><title>New full-text search queries</title><link>http://community.instantasp.co.uk/Topic10211-51-1.aspx</link><description>I built a fast full-text search feature for my forum a couple of years ago. I started porting it to IF earlier today. It's mostly done but I'm not proficient with .NET and don't know the IF source very well yet. Here's my numbers and my source. (At the moment I think this only works from the advanced search page.) Also, my code doesn't support the Rank feature. I don't know how important/relevant rank is. I might be able to tweak it too support ranking if that's important.&lt;BR&gt;&lt;BR&gt;Searching against a database of 691,000 posts in all forums, all dates.&lt;BR&gt;&lt;BR&gt;I tested each search term twice and not in order. The same words were used for both freetext and contains tests. Also the same set was used to test my code vs. IF code. The IF code returns more results on some test terms so that would need to be investigated as well. The database server used is not dedicated to this application so the numbers vary a bit due to load. The numbers quoted are from the top of the search results page.&lt;BR&gt;&lt;BR&gt;[u]Freetext results:[/u]&lt;BR&gt;my code:&lt;BR&gt;8 character single word term - 135 topics returned in 0.86 seconds first attempt /.53 seconds second attempt&lt;BR&gt;7 character single word term - 315 topics in 6.256/2.856&lt;BR&gt;4 character single word - 260 topics in 2.733/2.403&lt;BR&gt;&lt;BR&gt;IF code:&lt;BR&gt;8 character single word term - 135 topics returned in 31.003 seconds first attempt /27.9 seconds&lt;BR&gt;7 character single word term - 375 topics in 45.210/35.640&lt;BR&gt;4 character single word - 314 topics in 36.730/65.98&lt;BR&gt;&lt;BR&gt;[u]Contains results:[/u]&lt;BR&gt;my code:&lt;BR&gt;8 character single word term - 136 topics returned in 0.770 seconds first attempt /2.9 seconds&lt;BR&gt;7 character single word term - 315 topics in 7.583/3.640&lt;BR&gt;4 character single word - 260 topics in 1.746/1.676&lt;BR&gt;&lt;BR&gt;IF code:&lt;BR&gt;8 character single word term - 136 topics returned in 93.860 seconds first attempt /31.75 seconds&lt;BR&gt;7 character single word term - 393 topics in 41.626/29.170&lt;BR&gt;4 character single word - 336 topics in 24.993/33.876&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;So, it's a bit faster. How do I do it? SQL server is much more efficient when working with sets (even huge sets) of data in derived tables than it is at doing complex joins between many tables. &lt;BR&gt;&lt;BR&gt;To use my admittedly sloppy code you have to do three things. 1) Create a user-defined function in your instantforum database. 2) Create a two-column index on InstantForum_topics using ForumID then PostID. (This prevents costly table scans during the full-text query.) 3) edit search.vb in \instantasp.instantforum\instantasp.instantforum\business&lt;BR&gt;&lt;BR&gt;[u]Step 1[/u]&lt;BR&gt;CREATE function if_fnInstantFullTextSubQuery(@searchtype tinyint=2,&lt;BR&gt;@strSearch nvarchar(1000),@searchwithin tinyint=1 )&lt;BR&gt;returns @returnset table (postid integer not null primary key)&lt;BR&gt;as&lt;BR&gt;&lt;BR&gt;/*Enum EnumSearchWithin&lt;BR&gt;EntirePost = 1&lt;BR&gt;TitlesOnly = 2&lt;BR&gt;MessageOnly = 3&lt;BR&gt;Enum EnumSearchType&lt;BR&gt;FreeTextTable = 2&lt;BR&gt;ContainsTable = 3&lt;BR&gt;*/&lt;BR&gt;&lt;BR&gt;begin&lt;BR&gt;&lt;BR&gt;if @searchtype = 3&lt;BR&gt;begin&lt;BR&gt;if @searchwithin=1 /*entire post*/&lt;BR&gt;begin&lt;BR&gt;/*get title matches */&lt;BR&gt;insert into @returnset SELECT DISTINCT a.postID FROM InstantForum_Topics a&lt;BR&gt;where (a.postid in (select z.postid from Instantforum_topics z where z.postid in &lt;BR&gt;(select x.postID from InstantForum_topics x where contains (x.title,@strSearch) &lt;BR&gt;)))&lt;BR&gt;insert into @returnset SELECT DISTINCT a.postID FROM InstantForum_Topics a&lt;BR&gt;where (a.postid not in (select postid from @returnset ) and &lt;BR&gt;(a.postid in (select z.postid from Instantforum_topics z where (z.postid in &lt;BR&gt;(select x.postID from InstantForum_Topics x where contains (x.description,@strSearch) &lt;BR&gt;)))))&lt;BR&gt;&lt;BR&gt;/*get post matches */&lt;BR&gt;insert into @returnset SELECT DISTINCT a.postID FROM InstantForum_Topics a&lt;BR&gt;where (a.postid not in (select postid from @returnset ) and &lt;BR&gt;(a.postid in (select z.postid from Instantforum_topics z where (z.postid in &lt;BR&gt;(select x.postID from InstantForum_messages x where contains (x.message,@strSearch) &lt;BR&gt;)))))&lt;BR&gt;end&lt;BR&gt;if @searchwithin=2 /* titles only */&lt;BR&gt;begin&lt;BR&gt;/*get title matches only*/&lt;BR&gt;insert into @returnset SELECT DISTINCT a.postID FROM InstantForum_Topics a&lt;BR&gt;where (a.postid in (select z.postid from Instantforum_topics z where (z.postid in &lt;BR&gt;(select x.postID from InstantForum_topics x where contains (x.title,@strSearch) &lt;BR&gt;))))&lt;BR&gt;insert into @returnset SELECT DISTINCT a.postID FROM InstantForum_Topics a&lt;BR&gt;where (a.postid not in (select postid from @returnset ) and &lt;BR&gt;(a.postid in (select z.postid from Instantforum_topics z where (z.postid in &lt;BR&gt;(select x.postID from InstantForum_topics x where contains (x.title,@strSearch) &lt;BR&gt;)))))&lt;BR&gt;&lt;BR&gt;end&lt;BR&gt;if @searchwithin=3 /* message only */&lt;BR&gt;begin&lt;BR&gt;/*get post matches only */&lt;BR&gt;insert into @returnset SELECT DISTINCT a.postID FROM InstantForum_Topics a&lt;BR&gt;where (a.postid in (select z.postid from Instantforum_topics z where (z.postid in &lt;BR&gt;(select x.postID from InstantForum_messages x where contains (x.message,@strSearch) &lt;BR&gt;))))&lt;BR&gt;end&lt;BR&gt;end&lt;BR&gt;if @searchtype=2&lt;BR&gt;/* freetext section */&lt;BR&gt;begin&lt;BR&gt;if @searchwithin=1 /*entire post*/&lt;BR&gt;begin&lt;BR&gt;/*get title matches */&lt;BR&gt;insert into @returnset SELECT DISTINCT a.postID FROM InstantForum_Topics a&lt;BR&gt;where (a.postid in (select z.postid from Instantforum_topics z where z.postid in &lt;BR&gt;(select x.postID from InstantForum_topics x where freetext (x.title,@strSearch) &lt;BR&gt;)))&lt;BR&gt;insert into @returnset SELECT DISTINCT a.postID FROM InstantForum_Topics a&lt;BR&gt;where (a.postid not in (select postid from @returnset ) and &lt;BR&gt;(a.postid in (select z.postid from Instantforum_topics z where (z.postid in &lt;BR&gt;(select x.postID from InstantForum_Topics x where freetext (x.description,@strSearch) &lt;BR&gt;)))))&lt;BR&gt;&lt;BR&gt;/*get post matches */&lt;BR&gt;insert into @returnset SELECT DISTINCT a.postID FROM InstantForum_Topics a&lt;BR&gt;where (a.postid not in (select postid from @returnset ) and &lt;BR&gt;(a.postid in (select z.postid from Instantforum_topics z where (z.postid in &lt;BR&gt;(select x.postID from InstantForum_messages x where freetext (x.message,@strSearch) &lt;BR&gt;)))))&lt;BR&gt;end&lt;BR&gt;if @searchwithin=2 /* titles only */&lt;BR&gt;begin&lt;BR&gt;/*get title matches only*/&lt;BR&gt;insert into @returnset SELECT DISTINCT a.postID FROM InstantForum_Topics a&lt;BR&gt;where (a.postid in (select z.postid from Instantforum_topics z where (z.postid in &lt;BR&gt;(select x.postID from InstantForum_topics x where freetext (x.title,@strSearch) &lt;BR&gt;))))&lt;BR&gt;insert into @returnset SELECT DISTINCT a.postID FROM InstantForum_Topics a&lt;BR&gt;where (a.postid not in (select postid from @returnset ) and &lt;BR&gt;(a.postid in (select z.postid from Instantforum_topics z where (z.postid in &lt;BR&gt;(select x.postID from InstantForum_topics x where freetext (x.title,@strSearch) &lt;BR&gt;)))))&lt;BR&gt;&lt;BR&gt;end&lt;BR&gt;if @searchwithin=3 /* message only */&lt;BR&gt;begin&lt;BR&gt;/*get post matches only */&lt;BR&gt;insert into @returnset SELECT DISTINCT a.postID FROM InstantForum_Topics a&lt;BR&gt;where (a.postid in (select z.postid from Instantforum_topics z where (z.postid in &lt;BR&gt;(select x.postID from InstantForum_messages x where freetext (x.message,@strSearch) &lt;BR&gt;))))&lt;BR&gt;end&lt;BR&gt;end&lt;BR&gt;&lt;BR&gt;return&lt;BR&gt;end&lt;BR&gt;&lt;BR&gt;[u]Step 2[/u]&lt;BR&gt;CREATE INDEX [ix_forumID_postID] ON [dbo].[InstantForum_Topics]([ForumID], [PostID]) ON [PRIMARY]&lt;BR&gt;&lt;BR&gt;(I actually have all of my non-clustred indexes stored on a separate volume so my create index statement is slightly different.)&lt;BR&gt;&lt;BR&gt;[u]Step 3[/u]&lt;BR&gt;&lt;BR&gt;Edit Shared Function ConstructManualSelectStatement in search.vb. Since it's not my code to be posting I won't post the whole function here. (I'd be happy to make it available to Ryan though.) The general idea is:&lt;BR&gt;&lt;BR&gt;Case Enumerations.EnumSearchWithin.TitlesOnly&lt;BR&gt;' search topic title index only&lt;BR&gt;' Tables.Append(", CONTAINSTABLE(InstantForum_Topics, *, '" &amp;amp; Keywords &amp;amp; "', " &amp;amp; ntFullTextResultLimit.ToString() &amp;amp; ") AS Topic")&lt;BR&gt;' add the full text key to the clustered post key&lt;BR&gt;'WhereClause.Append("(Topic.[Key] = InstantForum_Messages.PostID) AND ")&lt;BR&gt;WhereClause.Append(" instantforum_messages.postid in (select * from if_fnInstantFullTextSubQuery(3,'" &amp;amp; Keywords &amp;amp; "',2)) and ")&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;There are more changes to the function call but this gives you an idea of how the user-defined SQL function call is used to perform the full-text subquery.&lt;BR&gt;&lt;BR&gt;My code isn't elegant, it's more of a proof of concept that I hoped could be integrated into a future version of IF. With this type of change in IF then we might be able to roll it out of testing mode and onto a live production server.</description><pubDate>Mon, 27 Feb 2006 21:50:16 GMT</pubDate><dc:creator>Drew Black</dc:creator></item></channel></rss>