Tuesday, July 17, 2012

How to create custom search for seraching strings or set of strings a sharepoint list different columns through C# code.

I have created a console utility which can be very useful "To search a string or a set of string in different columns of sharepoint lists". It can be extended to so many level from search a string in a specific column of a specific list to search a string or set of strings in all columns of a all lists. But for that you need to do a lot of modifications. I have created a simple console which might be useful in extending it for practical use. Code for it as follows :

I have used  '-'  character as  separator for diving it into a sentence.

class Program
    {
        static void Main(string[] args)
        {
            using (SPSite objSPSite = new SPSite("http://serverName:portname/sites/TestPages"))
            {
                using (SPWeb objSPWeb = objSPSite.OpenWeb())
                {
                    SPList objSPListPoc1 = objSPWeb.Lists.TryGetList("listTitle");
                    if (objSPListPoc1 != null)
                    {
string toSearchEntered = "-This is a mandatory- training need to be -completed today- and as soon -as possible";
                        int countSeprator = CountChars('-', toSearchEntered);
                        if (isEven(countSeprator))
                        {
                            string toSearch = "-" + toSearchEntered + "-";
                            List<int> occurence = IndexOfNth(toSearch, '-');
                            /*foreach (int item in occurence)
                            {
                                Console.WriteLine(item + "\n");
                            }*/
                            List<string> stringsListToSearch = getSubStrings(toSearch, occurence);
                            /*foreach (string subString in stringsListToSearch)
                            {
                                Console.WriteLine(subString + "\n");
                            }*/
                            List<string> SearchStrings = getSearchStringsCollection(stringsListToSearch);
                            foreach (string splitedStrings in SearchStrings)
                            /*{
                                Console.WriteLine(splitedStrings + "\n");
                            }*/
                            StringBuilder stbQuery = GetQueryForAllDaysTCodes1(SearchStrings);
                            SPQuery objSPQuery = new SPQuery();
                            objSPQuery.Query = stbQuery.ToString();
                            SPListItemCollection objSPListItemCollection = objSPListPoc1.GetItems(objSPQuery);
                            if (objSPListItemCollection != null && objSPListItemCollection.Count > 0)
                            {
                                Console.WriteLine("Items found : " + objSPListItemCollection.Count);
                                foreach (SPListItem item in objSPListItemCollection)
                                {
                                    Console.WriteLine(item["ID"] + " " + item["Title"]);
                                }
                            }
                            else
                            {
                                Console.WriteLine("Item Not found");
                            }
                        }
                        else
                        {
                            Console.WriteLine("String contains odd number of -. Please remove or enclose it.");
                        }
                    }
                }
            }
            Console.WriteLine("Executed");
            Console.ReadLine();
        }

 public static List<int> IndexOfNth(string str, char c)
        {
            List<int> occuringAddress = new List<int>();
            for (int i = 0; i < str.Length; i++)
            {
                if (str[i] == c)
                {
                    occuringAddress.Add(i);
                }
            }
            occuringAddress.Add(str.Length);
            return occuringAddress;
        }

        public static List<string> getSubStrings(string toSearch, List<int> position)
        {
            List<string> stringsListToSearch = new List<string>();
            string substringSentenceSearch = string.Empty;
            if (position.Count() >= 0)
            {
                for (int i = 0; i <= position.Count - 2; i++)
                {
                    substringSentenceSearch = toSearch.Substring(position[i] + 1, (position[i + 1] - (position[i] + 1)));
                    stringsListToSearch.Add(substringSentenceSearch);
                }
            }
            return stringsListToSearch;
        }

        public static List<string> getSearchStringsCollection(List<string> splitedSerachString)
        {
            List<string> lstSearchStringsCollection = new List<string>();
            if (splitedSerachString.Count > 0)
            {
                for (int i = 0; i <= splitedSerachString.Count - 1; i++)
                {
                    if (i % 2 == 0)
                    {
                        List<string> temp = new List<string>();
                        temp = splitedSerachString[i].Split(' ').ToList();
                        if (temp != null && temp.Count > 0)
                        {
                            foreach (string item in temp)
                            {
                                lstSearchStringsCollection.Add(item);
                            }
                        }
                    }
                    else
                    {
                        lstSearchStringsCollection.Add(splitedSerachString[i]);
                    }
                }
            }
            return lstSearchStringsCollection;
        }

        public static int CountChars(char seprator, string value)
        {
            int result = 0;
            foreach (char c in value)
            {
                if (c == seprator)
                {
                    result++;
                }
            }
            return result;
        }

        public static bool isEven(int Count)
        {
            bool isEven = false;
            if (Count % 2 == 0)
            {
                isEven = true;
            }
            else
            {
                isEven = false;
            }
            return isEven;
        }

 public static StringBuilder GetQueryForAllDaysTCodes1(string[] Cities)
        {
            int loopCnt = 0, cityCnt = 0;
            StringBuilder stbQuery = new StringBuilder();
            stbQuery.Append("<Where>");
            bool first = true;
            foreach (string City in Cities)
            {
                if (Cities.Length > 0)
                {
                    for (int dataCnt = 0; dataCnt < (Cities.Length * 3) - 1; dataCnt++)
                        stbQuery.Append("<Or>");

                    for (int dataCnt = 0; dataCnt < Cities.Length; dataCnt++)
                    {
                        cityCnt++;
                        for (int fieldCnt = 0; fieldCnt <= 2; fieldCnt++)
                        {
                            loopCnt++;
                            switch (fieldCnt)
                            {
                                case 0:
                                    stbQuery.Append("<Contains><FieldRef Name='Column1' /><Value Type='Text'>" + Cities[dataCnt].TrimStart().TrimEnd() + "</Value></Contains>");
                                    break;
                                case 1:
                                    stbQuery.Append("<Contains><FieldRef Name='Column2' /><Value Type='Text'>" + Cities[dataCnt].TrimStart().TrimEnd() + "</Value></Contains>");
                                    break;
                                case 2:
                                    stbQuery.Append("<Contains><FieldRef Name='Column3' /><Value Type='Text'>" + Cities[dataCnt].TrimStart().TrimEnd() + "</Value></Contains>");
                                    break;
                            }
                            if (loopCnt >= 2 && cityCnt >= 1)
                                stbQuery.Append("</Or>");
                        }
                    }
                    stbQuery.Append("</Where>");
                }
            }
            return stbQuery;
        }

By increasing cases you can increase 'n' no. of columns. it will do an or query for all words splited by space. And string between -This is a mandatory- will be considered as a sentence and also searched as a sentence.

So result in the output screen will be like this.

You can modify received ListItemcollection as per your need and can use it in a Page or Webpart with Grid View or further processing. 

You can uncomment code to see all process step by step. Hope it helps you ...!!!

No comments:

Post a Comment