Finding suggested addresses from a key word in bing search service - c#

I have created a WPF application to find locations from the keyword entered. For that I have used bing maps service api my code is
private object SearchKeywordLocation(string keywordLocation)
{
String results = "";
SearchRequest searchRequest = new SearchRequest();
// Set the credentials using a valid Bing Maps key
searchRequest.Credentials = new SearchService.Credentials();
searchRequest.Credentials.ApplicationId = "my key";
//Create the search query
StructuredSearchQuery ssQuery = new StructuredSearchQuery();
string[] parts = keywordLocation.Split(';');
ssQuery.Keyword = parts[0];
ssQuery.Location = parts[1];
searchRequest.StructuredQuery = ssQuery;
//Define options on the search
searchRequest.SearchOptions = new SearchOptions();
searchRequest.SearchOptions.Filters =
new FilterExpression()
{
PropertyId = 3,
CompareOperator = CompareOperator.GreaterThanOrEquals,
FilterValue = 8.16
};
//Make the search request
SearchServiceClient searchService = new SearchServiceClient("BasicHttpBinding_ISearchService");
SearchResponse searchResponse = searchService.Search(searchRequest);
//Parse and format results
if (searchResponse.ResultSets[0].Results.Length > 0)
{
StringBuilder resultList = new StringBuilder("");
for (int i = 0; i < searchResponse.ResultSets[0].Results.Length; i++)
{
resultList.Append(String.Format("{0}. {1}\n", i + 1,
searchResponse.ResultSets[0].Results[i].Name));
}
results = resultList.ToString();
}
else
results = "No results found";
return results;
}
}
for this app. I am getting results when I am calling SearchKeywordLocation("sushi; Arvada, CO"); but my requirement is to get results when I call SearchKeywordLocation("new"); I should get results related to new york. this specific string formatting should be avoided. What I am doing wrong here?

The Search service is for points of interests and not addresses. New York falls into the category of an address and is something that should be passed through the geocoding service. That said, passing in "New" into any of the services would unlike to get the result you want as there are millions of possible results that have the word "new" in their name. Given this the geocoder will likely identify that this is a poor formed query and limit the possible results to only a few (testing "new" I see 5 results, New York was not one of them).
That said, you should also avoid using the old legacy SOAP services. They are nearing end of life and the documentation was taken offline a few years ago. In fact, we stopped recommending the SOAP services about 5 years ago and only kept them around for customers who have old apps running on them. These services were replaced with the Bing Maps services 5 years ago which have a lot more features and functionalities, are much faster, have smaller response objects and tend to return more accurate results. You can find documentation on using the REST services here: https://msdn.microsoft.com/en-us/library/ff701713.aspx
Here is some documentation on using them in .NET: https://msdn.microsoft.com/en-us/library/jj819168.aspxI
I've also been working on creating a nice .NET library that wraps the services to make them easier to use in these types of apps. If you are interested in testing it out, send me an email at ricky_brundritt at Hotmail.com and I'll send you over a copy of the library.

Related

Search using elasticsearch (contains)

I am developing my ASP.NET MVC application called eBookRepository that contains online books. Ebook has its own title, author etc. So right now I'm trying to implement my search mechanism. I must use Elasticsearch as search engine.
I have indexed my ebooks in this code, and it works.
Uri nodeLocation = new Uri("http://localhost:9200");
IConnectionPool connectionPool = new SniffingConnectionPool(new List<Uri> { nodeLocation });
ConnectionSettings settings = new ConnectionSettings(connectionPool).DefaultIndex("ebookrepository");
esClient = new ElasticClient(settings);
foreach (var ebook in ebooksService.GetAll())
{
IIndexResponse result = esClient.Index(ebook, i => i.Index("ebookrepository").Type("ebook").Id(ebook.ID));
}
Also if I search my ebooks by title, it works but only if search text is exactly same as ebook's title. Code doing that is here:
var search = esClient.Search<Ebook>(s => s.Source(sf => sf.IncludeAll()).Query(q => q.Term(p1 => p1.Title, searchString)));
searchString variable is string (text) that I type in text box on UI.
So I cant find similiar code like this above that should work like .contains method in C#, I was looking for right solution and I think I should use .Match instead of .Term (.Term return exact matching result), but I cant find right solution.
While I was looking for right solution a lot of questions and answers are in JSON format (I'm not good at it), I dont want that format, I need .NET code.
Based on the documentation you can use a Unstructured Search https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/writing-queries.html#unstructured-search
use this
var hits = _context.Search<Ebook>(search string, new SearchUrlParameters { Pretty = true });

How to create and use a HMM Dynamic Bayesian Network in Bayes Server?

I'm trying to build a prediction module implementing a Hidden Markov Model type DBN in Bayes Server 7 C#. I managed to create the network structure but I'm not sure if its correct because their documentation and examples are not very comprehensive and I also don't fully understand how the prediction is meant to be done in the code after training is complete.
Here is a how my Network creation and training code looks:
var Feature1 = new Variable("Feature1", VariableValueType.Continuous);
var Feature2 = new Variable("Feature2", VariableValueType.Continuous);
var Feature3 = new Variable("Feature3", VariableValueType.Continuous);
var nodeFeatures = new Node("Features", new Variable[] { Feature1, Feature2, Feature3 });
nodeFeatures.TemporalType = TemporalType.Temporal;
var nodeHypothesis = new Node(new Variable("Hypothesis", new string[] { "state1", "state2", "state3" }));
nodeHypothesis.TemporalType = TemporalType.Temporal;
// create network and add nodes
var network = new Network();
network.Nodes.Add(nodeHypothesis);
network.Nodes.Add(nodeFeatures);
// link the Hypothesis node to the Features node within each time slice
network.Links.Add(new Link(nodeHypothesis, nodeFeatures));
// add a temporal link of order 5. This links the Hypothesis node to itself in the next time slice
for (int order = 1; order <= 5; order++)
{
network.Links.Add(new Link(nodeHypothesis, nodeHypothesis, order));
}
var temporalDataReaderCommand = new DataTableDataReaderCommand(evidenceDataTable);
var temporalReaderOptions = new TemporalReaderOptions("CaseId", "Index", TimeValueType.Value);
// here we map variables to database columns
// in this case the variables and database columns have the same name
var temporalVariableReferences = new VariableReference[]
{
new VariableReference(Feature1, ColumnValueType.Value, Feature1.Name),
new VariableReference(Feature2, ColumnValueType.Value, Feature2.Name),
new VariableReference(Feature3, ColumnValueType.Value, Feature3.Name)
};
var evidenceReaderCommand = new EvidenceReaderCommand(
temporalDataReaderCommand,
temporalVariableReferences,
temporalReaderOptions);
// We will use the RelevanceTree algorithm here, as it is optimized for parameter learning
var learning = new ParameterLearning(network, new RelevanceTreeInferenceFactory());
var learningOptions = new ParameterLearningOptions();
// Run the learning algorithm
var result = learning.Learn(evidenceReaderCommand, learningOptions);
And this is my attempt at prediction:
// we will now perform some queries on the network
var inference = new RelevanceTreeInference(network);
var queryOptions = new RelevanceTreeQueryOptions();
var queryOutput = new RelevanceTreeQueryOutput();
int time = 0;
// query a probability variable
var queryHypothesis = new Table(nodeHypothesis, time);
inference.QueryDistributions.Add(queryHypothesis);
double[] inputRow = GetInput();
// set some temporal evidence
inference.Evidence.Set(Feature1, inputRow[0], time);
inference.Evidence.Set(Feature2, inputRow[1], time);
inference.Evidence.Set(Feature3, inputRow[2], time);
inference.Query(queryOptions, queryOutput);
int hypothesizedClassId;
var probability = queryHypothesis.GetMaxValue(out hypothesizedClassId);
Console.WriteLine("hypothesizedClassId = {0}, score = {1}", hypothesizedClassId, probability);
Here I'm not even sure how to "Unroll" the network properly to get the prediction and what value to assign to the variable "time". If someone can shed some light on how this toolkit works, I would greatly appreciate it. Thanks.
The code looks fine except for the network structure, which should look something like this for an HMM (the only change to your code is the links):
var Feature1 = new Variable("Feature1", VariableValueType.Continuous);
var Feature2 = new Variable("Feature2", VariableValueType.Continuous);
var Feature3 = new Variable("Feature3", VariableValueType.Continuous);
var nodeFeatures = new Node("Features", new Variable[] { Feature1, Feature2, Feature3 });
nodeFeatures.TemporalType = TemporalType.Temporal;
var nodeHypothesis = new Node(new Variable("Hypothesis", new string[] { "state1", "state2", "state3" }));
nodeHypothesis.TemporalType = TemporalType.Temporal;
// create network and add nodes
var network = new Network();
network.Nodes.Add(nodeHypothesis);
network.Nodes.Add(nodeFeatures);
// link the Hypothesis node to the Features node within each time slice
network.Links.Add(new Link(nodeHypothesis, nodeFeatures));
// An HMM also has an order 1 link on the latent node
network.Links.Add(new Link(nodeHypothesis, nodeHypothesis, 1));
It is also worth noting the following:
You can add multiple distributions to 'inference.QueryDistributions' and query them all at once
While it is perfectly valid to set evidence manually and then query, see EvidenceReader, DataReader and either DatabaseDataReader or DataTableDataReader, if you want to execute the query over multiple records.
Check out the TimeSeriesMode on ParameterLearningOptions
If you want the 'Most probable explanation' set queryOptions.Propagation = PropagationMethod.Max; // an extension of the Viterbi algorithm for HMMs
Check out the following link:
https://www.bayesserver.com/docs/modeling/time-series-model-types
An Hidden Markov model (as a Bayesian network) has a discrete latent variable and a number of child nodes. In Bayes Server you can combine multiple variables in a child node, much like a standard HMM. In Bayes Server you can also mix and match discrete/continuous nodes, handle missing data, and add additional structure (e.g. mixture of HMM, and many other exotic models).
Regarding prediction, once you have built the structure from the link above, there is a DBN prediction example at https://www.bayesserver.com/code/
(Note that you can predict an individual variable in the future (even if you have missing data), you can predict multiple variables (joint probability) in the future, you can predict how anomalous the time series is (log-likelihood) and for discrete (sequence) predictions you can predict the most probable sequence.)
It it is not clear, ping Bayes Server Support and they will add an example for you.

IPP .NET c# SDK allows query filters, but this does not reduce payload?

Referencing the following IPP Documentation:
https://developer.intuit.com/docs/0025_quickbooksapi/0055_devkits/0150_ipp_.net_devkit_3.0/query_filters
I made the assumption that the following code using the Linq Extentions Projection would alter the request and reduce the payload of the response by only querying for the requested fields and only including those fields (narrow result set) in the response:
public List<ShortAccount> GetFullShortAccountList(bool logRequestResponse)
{
var accounts = new List<ShortAccount>();
var accountQueryService = new QueryService<Account>
(GetIppServiceContext(logRequestResponse));
var selected = accountQueryService.Select(a => new { a.Id, a.Name });
foreach (var account in selected)
{
accounts.Add(new ShortAccount { Id = account.Id, Name = account.Name });
}
return accounts;
}
Now the behavior of this method is as expected, but if I look at the request/response logs (or the actual request and response using Fiddler) the request doesn't change -- it is still "Select * from Account", and the response still includes all the other properties in the Account entity.
In other words, the payload is not reduced one iota.
Am I doing something wrong here? Or do I just understand this incorrectly?
How can I use the SDK to generate a query that would look more like "Select Id, Name from Account", and only return that result set?
Related question -- if this mode of query filtering does not reduce the payload, what is its purpose? You might as well get the whole shebang and just take the fields you need?
Thanks in advance.
That's right #Barrick. The implementation of our query providers is not exactly the same as the standard LINQ. So, Stephan, that's the issue.
If you just want to get specific fields I would suggest you to use IDSQuery like:
QueryService<Account> AccQueryService22 = new QueryService<Account>(context);
var t13 = AccQueryService22.ExecuteIdsQuery("Select Id, Name From Account Where Active in (true, false)");
I will forward the feedback to our team.
Thanks!

Lucene.Net to weigh descriptions with the same word in it multiple times, higher score

I am trying to figure out how I can add more weight to a description that has the same word multiple times in it to appear first for the lucene.net in c#.
Example:
Pre-condition:
Lets say I have a list of items like this:
Restore Exchange
Backup exchange
exchange is a really great tool, exchange can have many mailboxes
Scenario:
I search for exchange.
The list would be returned in this order:
(it has the same weight as 2 and it was added to the index first)
(it has the same weight as 1 and it was added to the index second)
(has a reference of exchange in it, but its length is greater then 1 and 2)
So I am trying to get #3 to show up first as it has exchange in the description more then one time.
Here is some code showing that I set the Similarity:
// set up lucene searcher
using (var searcher = new IndexSearcher(directory, false))
{
var hits_limit = 1000;
var analyzer = new StandardAnalyzer(Version.LUCENE_29);
searcher.Similarity = new test();
// search by single field
if (!string.IsNullOrEmpty(searchField))
{
var parser = new QueryParser(Version.LUCENE_29, searchField, analyzer);
var query = parseQuery(searchQuery, parser);
var hits = searcher.Search(query, hits_limit).ScoreDocs;
var results = mapLuceneToDataList(hits, searcher);
analyzer.Close();
searcher.Dispose();
return results;
}
// search by multiple fields (ordered by RELEVANCE)
else
{
var parser = new MultiFieldQueryParser
(Version.LUCENE_29, new[] { "Id", "Name", "Description" }, analyzer);
var query = parseQuery(searchQuery, parser);
var hits = searcher.Search
(query, null, hits_limit, Sort.RELEVANCE).ScoreDocs;
var results = mapLuceneToDataList(hits, searcher);
analyzer.Close();
searcher.Dispose();
return results;
}
Disclaimer: I can only speak about Lucene (and not Lucene.NET) but I believe they are built using the same principles.
The reason why documents #1 & #2 come up first is because field weights (1/2 for #1, 1/2 for #2) are higher than 2/11 for #3 (assuming you are not using stop words). The point here is that "exchange" term in first two documents has far more weight than in the third where it's more diluted. This is how default similarity algorithm works. In practice this is a bit more complex, as you can observe in the given link.
So what you are asking for is an alternative similarity algorithm. There's a similar discussion here where MySim, I believe, attempts to achieve something close to what you want. Just don't forget to set this similarity instance to both index writer and searcher.

Twitterizer - C# Code to Search Tweets From Only Users I Follow

I am currently using Twitterizer to search through public tweets using C#:
private void QueryTwitter()
{
SearchOptions myOptions = new SearchOptions();
myOptions.CacheTimespan = new TimeSpan(0, 15, 0);
//myOptions.ResultType = SearchOptionsResultType.Popular;
string searchTerm = "\"" + Player.GetPlayer(this.PlayerID).FullName + "\"";
TwitterResponse<TwitterSearchResultCollection> recentTweets = TwitterSearch.Search(searchTerm, myOptions);
repTweets.DataSource = recentTweets.ResponseObject;
repTweets.DataBind();
}
What I'd like to do is search through tweets from only the people that I follow. Is there any way to do this?
The search api is a non-authenticated endpoint, so it does not have any knowledge of who you are. Because of this, there is no baked in way of filtering tweets to only show people that you follow.
It is possible, however, to construct a query that specifies the author of tweets, if you add something like this to your query: (from:user1 OR from:user2 OR from:user3)
For example, my query string would be: "stream (from:twitterapi OR from:sitestreams)"
Keep in mind that the search api has complexity limits, so you will not be able to request all of your followers in a single query. If I were to guess, I'd say you'll get no more than 5 users at a time. You'll have to combine the results into a single list yourself.

Categories