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.
Related
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 });
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.
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!
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.
I am using the Lucene.NET API directly in my ASP.NET/C# web application. When I search using a wildcard, like "fuc*", the highlighter doesn't highlight anything, but when I search for the whole word, like "fuchsia", it highlights fine. Does Lucene have the ability to highlight using the same logic it used to match with?
Various maybe-relevant code-snippets below:
var formatter = new Lucene.Net.Highlight.SimpleHTMLFormatter(
"<span class='srhilite'>",
"</span>");
var fragmenter = new Lucene.Net.Highlight.SimpleFragmenter(100);
var scorer = new Lucene.Net.Highlight.QueryScorer(query);
var highlighter = new Lucene.Net.Highlight.Highlighter(formatter, scorer);
highlighter.SetTextFragmenter(fragmenter);
and then on each hit...
string description = Server.HtmlEncode(doc.Get("Description"));
var stream = analyzer.TokenStream("Description",
new System.IO.StringReader(description));
string highlighted_text = highlighter.GetBestFragments(
stream, description, 1, "...");
And I'm using the QueryParser and the StandardAnalyzer.
you'll need to ensure you set the parser rewrite method to SCORING_BOOLEAN_QUERY_REWRITE.
This change seems to have become necessary since Lucene v2.9 came along.
Hope this helps,