Thursday, August 1, 2013

Amazon's CloudSearch: Implementation using C#.Net (dotnet)

Amazon's CloudSearch: Implementation using C#.Net (dotnet)

 After working with DTSearch for long time, we switched over to Amazon's Cloud service. The factor for shifting was just the auto scalability feature in Amazon's Cloud Search as we need to worry for scalability issues with DTSearch.

 What is Amazon CloudSearch?

Amazon CloudSearch is a fully-managed service in the AWS Cloud that makes it easy to set up, manage, and scale a search solution for your website or application. Amazon CloudSearch enables you to search large collections of data such as web pages, document files, forum posts, or product information. Built for high throughput and low latency, Amazon CloudSearch supports a rich set of features including free text search, faceted search, customizable relevance ranking, configurable search fields, text processing options, and near real-time indexing.

To use Amazon CloudSearch, you simply:
1. Create a search domain
2. Configure your search fields
3. Upload your data for indexing, and
4. Submit search requests from your website or application

You can get more details at : http://aws.amazon.com/cloudsearch/

You can use Amazon CloudSearch to index and search both structured data and plain text. Amazon CloudSearch supports full text search, searching within fields, prefix searches, Boolean searches, and faceting. You can get search results in JSON or XML, sort and filter results based on field values, and rank results alphabetically, numerically, or according to custom rank expressions.

To build a search solution with Amazon CloudSearch, you:

1. Create and configure a search domain. A search domain encapsulates your searchable data and the search instances that handle your search requests. You set up a separate domain for each different data set you want to search.

2. Upload the data you want to search to your domain. Amazon CloudSearch automatically indexes your data and deploys the search index to one or more search instances.

3. Search your domain. You send a search request to your domain's search endpoint as an HTTP/HTTPS
GET request.

You can use Amazon's CloudSearch developer guide to know more:
Http://docs.aws.amazon.com/cloudsearch/latest/developerguide/SvcIntro.html

Amazon does not support the .net implementation for CloudSearch in its .net SDK. Here is the c# code you can use to get Amazon Cloudsearch implemented to post and get search requests from search indexes

namespace AmazonCloudSearch
{
    /// <summary>
    /// Data Formats in Cloud Search
    /// </summary>
    public enum DataFormat
    {
        Json,Xml
    }

    public class CloudSearch
    {

        /// <summary>
        /// Used to Add/Update/Delete Document batch data to Amazon Cloud Search
        /// </summary>
        /// <param name="JsonFormat"></param>
        /// <param name="DocumentUri"></param>
        /// <param name="ApiVersion"></param>
        /// <returns>Response Status</returns>    
        public string PostDocuments(string JsonFormat, string DocumentUri, string ApiVersion, DataFormat format)
        {
            try
            {
                var request = (HttpWebRequest)
                WebRequest.Create(string.Format("http://{0}{1}batch", DocumentUri, ApiVersion));
                request.ProtocolVersion = HttpVersion.Version11;
                request.Method = "POST";
                byte[] postBytes = Encoding.UTF8.GetBytes(JsonFormat);              
                request.ContentLength = postBytes.Length;
                request.Accept = "application/json";
                request.ContentType = format == DataFormat.Xml ? "text/xml;charset=utf-8" : "application/json;charset=utf-8";
                var requestStream = request.GetRequestStream();
                requestStream.Write(postBytes, 0, postBytes.Length);
                requestStream.Close();
                HttpWebResponse response = null;
                response = (HttpWebResponse)request.GetResponse();
                var retVal = new StreamReader(stream: response.GetResponseStream()).ReadToEnd();
                var statusCode = response.StatusCode;
                return statusCode + retVal;
            }
            catch (WebException Ex)
            {
                throw Ex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        /// <summary>
        /// Used to make search Request to Amazon Cloud Search
        /// </summary>
        /// <param name="SearchUri"></param>
        /// <param name="SearchQuery"></param>
        /// <param name="ReturnFields"></param>
        /// <param name="PageSize"></param>
        /// <param name="Start"></param>
        /// <returns>Response Status</returns>      
        public string SearchRquest(string SearchUri, string SearchQuery, string ReturnFields, int PageSize, int Start, DataFormat format)
        {
            try
            {
                string SearchUrl = SearchUri + SearchQuery + "&return-fields=" + ReturnFields + "&start=" + Start + "&size=" + PageSize;
                if (format == DataFormat.Xml)
                    SearchUrl = SearchUrl + "&results-type=xml";

                string responseFromServer = string.Empty;
                // Create a request for the URL.
                WebRequest request = WebRequest.Create(SearchUrl);
                // If required by the server, set the credentials.
                request.Credentials = CredentialCache.DefaultCredentials;
                request.ContentType = "application/json";
                // Get the response.
                WebResponse response = request.GetResponse();
                // Get the stream containing content returned by the server.
                Stream dataStream = response.GetResponseStream();
                // Open the stream using a StreamReader for easy access.
                StreamReader reader = new StreamReader(dataStream);
                // Read the content.
                responseFromServer = reader.ReadToEnd();
                // Clean up the streams and the response.
                reader.Close();
                response.Close();
                //returns response from the server
                return responseFromServer;
            }
            catch (WebException Ex)
            {
                throw Ex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}

Here is the code snippet we can use to use the above class in code:

AmazonCloudSearch.CloudSearch ObjCloudSearch = new AmazonCloudSearch.CloudSearch();
string strResponse = string.Empty;
if (IsSortByViews)
   strQuery = strQuery + "&rank=-vw";
else if (isSortByLatest)
   strQuery = strQuery + "&rank=-pid";
//Call Amazon Cloud Search API Service -- views and contentid are the indexed fields
strResponse = ObjCloudSearch.SearchRquest(configSection.SearchUri, strQuery, strReturnFields, p_intPageSize, p_intStart, AmazonCloudSearch.DataFormat.Json);


 You can create strQuery using the search criteria using the syntax as given in developer guide.

Monday, February 25, 2013

Windows Azure based new Bing Search API


Microsoft came up with the Bing Search few years back to compete with the Google search with an edge for the developers to create their own solutions based on it. Microsoft exposed its public search API to be easily used by the developer community around the globe.
The Bing Search API enables developers to embed and customize search results in applications or websites using XML or JSON. Add search functionality to a website, create unique consumer or enterprise apps, or develop new mash-ups. The Bing Search API gives you access to web, image, news, and video results, as well as related search and spelling suggestions. Microsoft came up with Bing Search API 2.0 earlier.
With introduction of Windows Azure, the bing Search API 2.0 is transitioned to new cloud-based data service, that is available via subscription based on usage requirements. The new cloud-based Bing Search API enables developer community to create their own applications using it to search, get and use the available data store provided by Bing. They can also analyze the data online using the new Service Explorer tool.

The new version of the Bing Search API includes:
•             Metered subscription of query limits.
•             HTTPS query URLs (sometimes called "endpoints") that provide results in either XML or JSON media formats.
•             Open Data Protocol (OData) support for easy consumption across multiple development systems.
•             Improved support for data types.
•             The ability to monetize applications in the Windows Azure Marketplace.
•             Access to fresher results and improved relevance.

For users of old Bing Search API 2.0, the migration documents are provided at Windows Azure Marketplace to move to new and fresh cloud based Bing Search API.

I was user of Old Bing Search API 2.0; we migrated to new cloud based search API after our product code broke suddenly. The changes were made at hours’ time. There are two issues I face, when we moved to new API. First, the code was written in .Net 2.0, so the new BingSearchContainer.cs  provided at Windows Azure Marketplace did not work as such as this file requires version 4.0.
 Following is the list of changes to be made to migrate to new bing search api.
1. Change your api service root url to https://api.datamarket.azure.com/Bing/Search/
2. Get the BING ACCOUNT KEY


Using new BingsearchContainer.cs as provided at Windows Azure marketplace:
internal class SearchBing : SearchWeb, IDisposable
 {
                Dictionary<SettingFields, string> _optionalParameters;
                List<Dictionary<SearchResultFields, string>> _newPage;
                const string SEARCHAPISERVICEURI = "https://api.datamarket.azure.com/Bing/Search/";
const string BINGACCOUNTKEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Set your account key here in place
      
                internal Dictionary<SettingFields, string> OptionalParameters
                {
                                set
                                {
                                                _optionalParameters = value;
                                }
                }


       

                internal List<Dictionary<SearchResultFields, string>> NewPage
                {
                get
                {
                                return _newPage;
                }
                 }                            

                internal void Search(string _searchQuery, uint _offset)
                {

                                var _bingSearchAzure  =  new BingSearchContainer(new             Uri(SEARCHAPISERVICEURI));
_bingSearchAzure.Credentials = new System.Net.NetworkCredential(BINGACCOUNTKEY, BINGACCOUNTKEY);
                                string options = String.Empty;


            if (_optionalParameters != null)
                options = SetOptionalParameters();

var _searchResponse = _bingSearchAzure.Image(_searchQuery, null, null, "strict", null, null, options);
            _searchResponse = _searchResponse.AddQueryOption("$top", this._resultsPerPage);
            _searchResponse = _searchResponse.AddQueryOption("$skip", _offset);
           
           
            var result = _searchResponse.Execute();
            this.TotalResults = 1000;
            _newPage = new List<Dictionary<SearchResultFields, string>>();
            foreach(ImageResult _result  in result)
            {
Dictionary<SearchResultFields, string> _newResult = new Dictionary<SearchResultFields, string>();
                                _newResult.Add(SearchResultFields.ThumbnailURL, _result.Thumbnail.MediaUrl);
                                _newResult.Add(SearchResultFields.ThumbnailHeight, _result.Thumbnail.Height.ToString());
                                _newResult.Add(SearchResultFields.ThumbnailWidth, _result.Thumbnail.Width.ToString());
                _newResult.Add(SearchResultFields.MainImageURL, _result.MediaUrl);
                _newResult.Add(SearchResultFields.Source, _result.SourceUrl);
                                _newResult.Add(SearchResultFields.Title, _result.Title);
                                 _newResult.Add(SearchResultFields.Height, _result.Height.ToString());
                                _newResult.Add(SearchResultFields.Width, _result.Width.ToString());
                                _newResult.Add(SearchResultFields.Size, _result.FileSize.ToString());
                                _newPage.Add(_newResult);
                
            }
           
                }
               

                private string [] SetOptionalParameters()
                {
           
            _parametersArray = new string[_optionalParameters.Count];
            int _index = 0;
            foreach (KeyValuePair<SettingFields, string> _parameters in _optionalParameters)
            {
                                _parametersArray[_index] = _parameters.Key.ToString() + ":" + _parameters.Value;
                _index = _index + 1;
            }
            return _parametersArray ;

                 }
}



Using the new Bing Search API using webrequest (Workable solution for any framework):


internal class SearchBing : SearchWeb, IDisposable
 {

                Dictionary<SettingFields, string> _optionalParameters;
                List<Dictionary<SearchResultFields, string>> _newPage;
                const string SEARCHAPISERVICEURI = "https://api.datamarket.azure.com/Bing/Search/";
                const string BINGACCOUNTKEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Set your       account key here in place
      
                internal Dictionary<SettingFields, string> OptionalParameters
              {
                  set
                {
                     _optionalParameters = value;
                }
             }


       

        internal List<Dictionary<SearchResultFields, string>> NewPage
        {
            get
            {
                return _newPage;
            }
        }                     

         internal void Search(string _searchQuery, uint _offset)
        {

string imageSearchQueryUrl = SEARCHAPISERVICEURI + "Image?Query=%27" + _searchQuery + "%27&$top=" + this._resultsPerPage + "&$skip=" + _offset + "&$Options=%27" + System.Web.HttpUtility.UrlEncode(SetOptionalParameters()) + "%27" ;
      
            XmlDocument xmlParseDom = new XmlDocument();
System.Net.NetworkCredential accountCredential = new System.Net.NetworkCredential(BINGACCOUNTKEY, BINGACCOUNTKEY);
            XmlUrlResolver resolver = new XmlUrlResolver();
            resolver.Credentials = accountCredential;

            xmlParseDom.XmlResolver = resolver;
            xmlParseDom.Load(imageSearchQueryUrl);
    
            XmlNamespaceManager namespaceMgr = new XmlNamespaceManager(xmlParseDom.NameTable);
            namespaceMgr.AddNamespace("atom","http://www.w3.org/2005/Atom");
            namespaceMgr.AddNamespace("m","http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
            namespaceMgr.AddNamespace("d","http://schemas.microsoft.com/ado/2007/08/dataservices");
           
string nextResultSet = xmlParseDom.SelectSingleNode("/atom:feed/atom:link[@rel='next']/@href", namespaceMgr).Value;

XmlNodeList imageresults =           xmlParseDom.SelectNodes("/atom:feed/atom:entry/atom:content/m:properties",namespaceMgr);

            this.TotalResults = 1000;
            _newPage = new List<Dictionary<SearchResultFields, string>>();
            foreach(XmlNode _result in imageresults)
            {
                     Dictionary<SearchResultFields, string> _newResult = new Dictionary<SearchResultFields, string>();

                     XmlNodeList thumbnailNodelst = _result.LastChild.ChildNodes;
                     foreach (XmlNode xmlthumbnailNode in thumbnailNodelst)
                     {
                         if (xmlthumbnailNode.Name == "d:MediaUrl")
                            _newResult.Add(SearchResultFields.ThumbnailURL, xmlthumbnailNode.ChildNodes[0].InnerText);
                         if (xmlthumbnailNode.Name == "d:Width")
                            _newResult.Add(SearchResultFields.ThumbnailWidth, xmlthumbnailNode.ChildNodes[0].InnerText);
                         if (xmlthumbnailNode.Name == "d:Height")
                            _newResult.Add(SearchResultFields.ThumbnailHeight, xmlthumbnailNode.ChildNodes[0].InnerText);
                     }
_newResult.Add(SearchResultFields.MainImageURL, _result.SelectSingleNode(".//d:MediaUrl", namespaceMgr).InnerText);
_newResult.Add(SearchResultFields.Source, _result.SelectSingleNode(".//d:SourceUrl", namespaceMgr).InnerText);
                                _newResult.Add(SearchResultFields.Title, _result.SelectSingleNode(".//d:Title", namespaceMgr).InnerText);
_newResult.Add(SearchResultFields.Height, _result.SelectSingleNode(".//d:Height", namespaceMgr).InnerText);
_newResult.Add(SearchResultFields.Width, _result.SelectSingleNode(".//d:Width", namespaceMgr).InnerText);
_newResult.Add(SearchResultFields.Size, _result.SelectSingleNode(".//d:FileSize", namespaceMgr).InnerText);

                                _newPage.Add(_newResult);
                 }
           
}
               

private string SetOptionalParameters()
{
            string  _parametersString = String.Empty;
            int _index = 0;
            foreach (KeyValuePair<SettingFields, string> _parameters in _optionalParameters)
            {
                if (_index > 0)
                    _parametersString = _parametersString + "+";
                _parametersString = _parametersString + _parameters.Key.ToString() + ":" + _parameters.Value;
                _index = _index + 1;
            }
            return _parametersString;

   }
}


Wednesday, October 3, 2012

Amazon's new cloud based Data storage service: Amazon Glacier

Amazon's new cloud based Data storage service: Amazon Glacier

Businesses are created or updated based on the usage data collected over a lifetime. And in its lifetime business can create Terabytes of data. The storage of this tons of data can be a nightmare for you at some stage. Today many of the businnesses are going the cloud way. According to a 2011 poll, 84 percent of businesses reported a noticeable savings with cloud computing. On an average, that savings was about 21 percent annually. With the growth of businesses turing to Cloud storage in near time, Amazon's Glacier cloud service can turn out to be best and low cost option for you, if your business requires Data storage or its archiving.

Amazon recently released its new innovative service Glacier. Glacier will revolutionalize the cloud storage with the following benefits:-

1. Extremely low-cost:- Business houses or companies pay hefty amount for the developing and maintaining varioues Data archiving solutions apart from the ongoing cost for operational expenses such as power, facilities, staffing, and maintenance etc. They need to manage the unexpected growth and capacity ratio as well. Sometimes the money is wasted due to this. With Amazon Glacier, you pay only for what you use. Amazon Glacier changes the way how you archive your data and its backup as you pay nothing upfront, pay a very low price for storage, and can scale your usage up or down as needed, while AWS handles all of the operational heavy lifting required to do data retention well.

2. Secure Storage/Transfer:- This service provides highly secure storage and transfer of data. Amazon Glacier supports secure transfer of your data over Secure Sockets Layer (SSL) and automatically stores data encrypted at rest using Advanced Encryption Standard (AES) 256, a secure symmetric-key encryption standard using 256-bit encryption keys. You can also control access to your data using AWS Identity and Access Management (IAM). IAM enables organizations with multiple employees to create and manage multiple users under a single AWS account and to set resource-based access policies.

3. Durable:- Amazon's Glacier is designed in such a way that it provides annual durability of 99.9999 for any business archive. The service redundantly stores data in multiple facilities and on multiple devices within each facility. To increase durability, Amazon Glacier synchronously stores your data across multiple facilities
before returning SUCCESS on uploading archives. Unlike traditional systems which can require laborious data verification and manual repair, Glacier performs regular, systematic data integrity checks and is built to be automatically self-healing.

4. Flexible:– Amazon Glacier automatically scales to meet your growing and often unpredictable storage requirements. There is no limit to the amount of data you can store in the service. Whether you’re storing petabytes or gigabytes, Glacier automatically scales your storage up or down as needed. In addition, you can choose to store your data in the Amazon Glacier Region that meets your regulatory, throughput, and geographic redundancy criteria.

5. Simple:– It only takes a few clicks in the AWS Management Console to set up Amazon Glacier and then you can upload any amount of data you choose. Traditional storage hardware is only supported for a limited number of years. With Amazon Glacier, customers no longer need to manage the expensive, time-consuming, and risky hardware and storage media migrations that are inevitable when your data retention period exceeds the lifetime of your storage hardware. Data uploaded to Amazon Glacier remains safely stored for as long as it is needed with no additional effort from customers.

Amazon Glacier is an extremely low-cost storage service that provides secure and durable storage for data archiving and backup. With Amazon Glacier, customers can reliably store large or small amounts of data for as little as $0.01 per gigabyte per month, a significant savings compared to traditional storage options.You can explore more at Amazon for pricing and integration details.



Monday, June 4, 2012

Switching a job- Here are few tips and tricks

Switching a job- Here are few tips and tricks


Mr 'Jobsearcher' is working in good "Startup" company, as of now, from last 7 long years, but the story is different for him now. He has over-grown (or say budget constraint of startup) in this company  and it seems, he is on the verge of losing his job. So, he started preparing for job change and that too, when he is down with an entire company’s implosion.You  find yourself amidst all sorts of perplexion of 'To DO' and 'Not To Do'. You are filled with with anguish, anger, depression and blah-blah, but at last u need to come out of the vex that engulfs your emotions. So I think Mr 'Jobsearcher' should start afresh with revitalized energy leavind behind the veils of confusion.
After long analysis, I find that the job search today is not what it was 5-6 years ago. Hers's a summary of what you need to do, if you think you are losing your job.

1. Review your resume: The very first thing, you need to do is to create a recreate ingeniously an efficacious resume which should clearly mention your dexterity and expertise. Try to co-relate your experience with current technologies in demand. YOur resume should hint at your conversence with latest technology even if you have not worked on it .There are many websites available online where you can get tips to create unbeatable resumes. You can also get help from some good consultant if possible.

2. Remember your old friends/colleagues: You should get in contact with all your friends and known ones. You should let them know that you are looking for job change desperately. Post your resume to all your friends and call them personally as well.

3. Online Social Networking: You should update your profile on social networking websites like LinkedIn, Twitter and Facebook. Be active on these websites and use these as the platforms for your self-marketing and profile promotions. In today's era, in my view, profile on LinkedIn is the most lethal weapon in job search market. 7 years ago, no body used social mediaut today no one can deny ithe influnce it can bring about .Push some posts showing your interests/expertise on Facebook and twitter. Social media has no limits, how you can use it. Your linked profile is your showcasing online. Showcase how you look, put up a good professional photograph of  yours on LinkedIn. Ask your colleagues, bosses and clients to put recommendations for you on LinkedIn. Join some good groups of your interests on LinkedIn and post your views there as well.

4. Brush up with all the skills that you have achieved all these years and start honing them.Get in touch wit the latest technology and its practical applicability. You should be well prepared to answer all the questions you think can be asked fromyour profile details. You should know every detail of your resume or profile. Be true to yourself and self analyse your strengths and weaknesses.

5. A task daily: You should do at-least one single task daily to be active online or offline. Task can be anything like saying "Hi" on G talk/Facebook to you old colleague or friend. It can be writing answers to group queries or writing a blog. Search for some good job consultants and be in contact with them.

6. Own a website or blog: I think this is most important and required thing you should do in present times. Create your website or blog to showcase your experience and skills. Create an influential profile of yours on your blog. Start writing a post  every week if not daily. You should put a link to your blog or website on your resume, profile on job search websites, LinkedIn, Facebook or twitter account.

The job search today has changed a lot, but you have to understand, what it requires to get the desired job.