Files
OurUmbraco/uSearch/Library/Xslt.cs
T
Sebastiaan Janssen 810cbd267f Initial commit
2012-12-17 09:41:11 +01:00

300 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;
using System.Web.UI;
using System.Xml.XPath;
using System.Text.RegularExpressions;
using Examine;
using Examine.LuceneEngine.Providers;
using Examine.Providers;
using System.Data.SqlClient;
using Examine.SearchCriteria;
using Examine.LuceneEngine.SearchCriteria;
namespace uSearch.Library {
public class Xslt {
public static string Reindex(bool async)
{
Businesslogic.Indexer i = new uSearch.Businesslogic.Indexer();
if (async)
i.AsyncReindex();
else
i.ReIndex();
return "";
}
public static string ReIndexVideo()
{
Businesslogic.Indexer i = new Businesslogic.Indexer();
//new EventHandlers.Video().Indexer_AfterReIndex(i, new Businesslogic.ReIndexEventArgs());
return "";
}
public static string ReIndexWiki()
{
Businesslogic.Indexer i = new Businesslogic.Indexer();
new EventHandlers.WikiHandler().Indexer_AfterReIndex(i, new Businesslogic.ReIndexEventArgs());
return "";
}
public static string ReIndexProjects()
{
Businesslogic.Indexer i = new Businesslogic.Indexer();
new EventHandlers.ProjectHandler().Indexer_AfterReIndex(i, new Businesslogic.ReIndexEventArgs());
return "";
}
public static string ReIndexForum()
{
Businesslogic.Indexer i = new Businesslogic.Indexer();
new EventHandlers.ForumHandler().Indexer_AfterReIndex(i, new Businesslogic.ReIndexEventArgs());
return "";
}
public static string[] GetKeywords(string text)
{
string[] stop = { "about", "after", "all", "also", "an", "and", "another", "any", "are", "as", "at", "be", "because", "been", "before", "being", "between", "both", "but", "by", "came", "can", "come", "could", "did", "do", "does", "each", "else", "for", "from", "get", "got", "has", "had", "he", "have", "her", "here", "him", "himself", "his", "how", "i", "if", "in", "into", "is", "it", "its", "just", "like", "make", "many", "me", "might", "more", "most", "much", "must", "my", "never", "now", "of", "on", "only", "or", "other", "our", "out", "over", "re", "said", "same", "see", "should", "since", "so", "some", "still", "such", "take", "than", "that", "the", "their", "them", "then", "there", "these", "they", "this", "those", "through", "to", "too", "under", "up", "use", "very", "want", "was", "way", "we", "well", "were", "what", "when", "where", "which", "while", "who", "will", "with", "would", "you", "your", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "$", "£", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };
char[] splitChars = { ' ', '\'' };
string[] words = text.Split(splitChars);
var keywordCount = (from keyword in words.Except(stop)
group keyword by keyword into g
select new { Keyword = g.Key, Count = g.Count() });
return keywordCount.OrderByDescending(k => k.Count).Select(k => k.Keyword).Take(5).ToArray();
}
public static string BuildExamineString(string term, int boost, string field)
{
var terms = term.Split(' ');
var qs = field + ":";
qs += "\"" + term + "\"^" + (boost + 30000).ToString() + " ";
qs += field + ":(+" + term.Replace(" ", " +") + ")^" + (boost + 5).ToString() + " ";
qs += field + ":(" + term + ")^" + boost.ToString() + " ";
return qs;
}
//convert ID to lucene friendly path eg: 1123 -> 1234s1232s1123s
public static string LucenePath(int nodeId) {
umbraco.presentation.nodeFactory.Node umbNode = new umbraco.presentation.nodeFactory.Node(nodeId);
string path = "";
if (umbNode != null) {
path = umbNode.Path.Replace("-1,", "").Replace(",", new Businesslogic.Settings().PathSplit);
}
return path;
}
public static XPathNodeIterator LucenePager(int currentPage, int totalPages) {
XmlDocument xmlDoc = new XmlDocument();
XmlNode root = xmlDoc.CreateElement("pages");
xmlDoc.AppendChild(root);
if (currentPage > totalPages)
currentPage = totalPages;
for (int i = 0; i < totalPages; i++) {
XmlNode page = xmlDoc.CreateElement("page");
page.Attributes.Append(umbraco.xmlHelper.addAttribute(xmlDoc, "index", i.ToString()));
if (i == currentPage)
page.Attributes.Append(umbraco.xmlHelper.addAttribute(xmlDoc, "current", "true"));
root.AppendChild(page);
}
return xmlDoc.CreateNavigator().Select(".");
}
//private static Query GetSafeQuery(MultiFieldQueryParser qp, String query) {
// Query q;
// try {
// q = qp.Parse(query);
// } catch (Lucene.Net.QueryParsers.ParseException e) {
// q = null;
// }
// if (q == null) {
// string cooked;
// cooked = Regex.Replace(query, @"[^\w\.@-]", " ");
// q = qp.Parse(cooked);
// }
// return q;
//}
public static XPathNodeIterator Lucene(string q, int currentPage, int trimAtChar, int pagesize)
{
return LuceneInContentType(q, string.Empty, currentPage, trimAtChar, pagesize);
}
public static XPathNodeIterator LuceneInContentType(string q, string types, int currentPage, int trimAtChar, int pagesize)
{
int _pageSize = pagesize;
int _page = currentPage;
int _fragmentCharacters = trimAtChar;
int _googleNumbers = 10;
int _TotalResults;
// Enable next, parent, headers and googleArrows
DateTime searchStart = DateTime.Now;
string queryText = q;
string[] _fields = {"name","content"};
q = q.Replace("-", "\\-");
new Page().Trace.Write("umbAdvancedSearch:doSearch", "Performing search! using query " + q);
/*
IndexSearcher searcher = new IndexSearcher( new uSearch.Businesslogic.Settings().IndexDirectory);
Analyzer analyzer = new StandardAnalyzer();
MultiFieldQueryParser mfqp = new MultiFieldQueryParser(_fields, analyzer);
Query mainquery = GetSafeQuery(mfqp,q);
BooleanQuery filterQuery = new BooleanQuery();
filterQuery.Add(mainquery, BooleanClause.Occur.MUST);
types = types.Trim(',');
if (!string.IsNullOrEmpty(types))
{
string typeQuery = "";
string[] t = types.Split(',');
for (int i = 0; i < t.Length; i++)
{
typeQuery += t[i];
if (i < t.Length - 1)
typeQuery += " OR ";
}
var parsedTypes = new QueryParser("contentType", analyzer).Parse(typeQuery);
filterQuery.Add(parsedTypes, BooleanClause.Occur.MUST);
}
Hits hits;
hits = searcher.Search(filterQuery);
*/
BaseSearchProvider Searcher = ExamineManager.Instance.SearchProviderCollection["ForumSearcher"];
var searchCriteria = Searcher.CreateSearchCriteria(BooleanOperation.Or);
var searchQuery = BuildExamineString(queryText,10, "Title");
searchQuery += BuildExamineString(queryText,7, "CommentsContent").TrimEnd(' ');
var searchFilter = searchCriteria.RawQuery(searchQuery);
IEnumerable<SearchResult> searchResults;
//little hacky just to get performant searching
if (pagesize > 0)
{
searchResults = Searcher.Search(searchFilter)
.OrderByDescending(x => x.Score).Take(pagesize);
}
else
{
searchResults = Searcher.Search(searchFilter)
.OrderByDescending(x => x.Score);
}
_TotalResults = searchResults.Count();
TimeSpan searchEnd = DateTime.Now.Subtract(searchStart);
string searchTotal = searchEnd.Seconds + ".";
for (int i = 4; i > searchEnd.Milliseconds.ToString().Length; i--)
searchTotal += "0";
searchTotal += searchEnd.Milliseconds.ToString();
// Check for paging
int pageSize = _pageSize;
int pageStart = _page;
if (pageStart > 0)
pageStart = _page * pageSize;
int pageEnd = (_page + 1) * pageSize;
//calculating total items and number of pages...
int _firstGooglePage = _page - Convert.ToInt16(_googleNumbers / 2);
if (_firstGooglePage < 0)
_firstGooglePage = 0;
int _lastGooglePage = _firstGooglePage + _googleNumbers;
if (_lastGooglePage * pageSize > _TotalResults)
{
_lastGooglePage = (int)Math.Ceiling(_TotalResults / ((double)pageSize)); // Convert.ToInt32(hits.Length()/pageSize)+1;
_firstGooglePage = _lastGooglePage - _googleNumbers;
if (_firstGooglePage < 0)
_firstGooglePage = 0;
}
// Create xml document
XmlDocument xd = new XmlDocument();
xd.LoadXml("<search/>");
xd.DocumentElement.AppendChild(umbraco.xmlHelper.addCDataNode(xd, "query", queryText));
xd.DocumentElement.AppendChild(umbraco.xmlHelper.addCDataNode(xd, "luceneQuery", q));
xd.DocumentElement.AppendChild(umbraco.xmlHelper.addTextNode(xd, "results", _TotalResults.ToString()));
xd.DocumentElement.AppendChild(umbraco.xmlHelper.addTextNode(xd, "currentPage", _page.ToString()));
xd.DocumentElement.AppendChild(umbraco.xmlHelper.addTextNode(xd, "totalPages", _lastGooglePage.ToString()));
XmlNode results = umbraco.xmlHelper.addTextNode(xd, "results", "");
xd.DocumentElement.AppendChild(results);
int highlightFragmentSizeInBytes = _fragmentCharacters;
// Print results
new Page().Trace.Write("umbSearchResult:doSearch", "printing results using start " + pageStart + " and end " + pageEnd);
int r = 0;
foreach (var sr in searchResults.Skip(pageStart).Take(pageSize))
{
XmlNode result = xd.CreateNode(XmlNodeType.Element, "result", "");
result.AppendChild(umbraco.xmlHelper.addTextNode(xd, "score", (sr.Score * 100).ToString()));
result.Attributes.Append(umbraco.xmlHelper.addAttribute(xd, "resultNumber", (r + 1).ToString()));
foreach (var field in sr.Fields)
{
result.AppendChild(umbraco.xmlHelper.addTextNode(xd, field.Key, field.Value));
}
results.AppendChild(result);
r++;
}
return xd.CreateNavigator().Select(".");
} //end search
}
}