Creating a free text-style search using Wpf/C#/EF5 - c#

I've created the bulk of a C# application, of which the core is a person database (there's a lot more going on peripherally too). I'm using EF with the CodeFirst/DbContext methodology. For my frontend, I have XAML using a MVVM type approach.
I would now like a search box which "feels" like a free-text search. I currently have an editable combo box, with properties set up to provide the correct feel. I am using EF's "Contains" query method to query the SQL database.
At present, I have something along the following lines:
x.Contains(p=> p.Forenames.Contains(s) || p.Surname.Contains(s))
Which works well to a limited extent. This is obviously a problem if "s", the search string, contains both first name and surname data. In essence, I want the user to be able to search by typing "Joe Bloggs" or "Bloggs, Joe" or various combinations of middle names etc... I may even want to add address data to the search in future.
My question is how I achieve this? The first way that springs to mind is to Split the string and then pass the individual components of the array to each search term, in a foreach loop. This could potentially result in multiple, rather large queries.
Is the a better way to achieve what I want to achieve through using a different query strategy with EF itself? I want to give the user the feeling that any search term they type provides something sensible in the combo box!

Related

C# translate database data using resx file

In my project (I am using azure storage) I have some data that I want to translate. I have the resource system in place for translations. I have a table in cloud which has name property. I want to translate it somehow.
One option is to create all the entries in database for each language which I don't prefer as it would create a lot entries along with the name.
Is there a smart way to use the resx mechanism I have in place?
So the table has multiple properties and one is name. Name could be anything like Mud, rock etc. Now I want to translate Mud into different language. Something like Texts.Mud would return me the correct value.
But lets say I get data like this
var data = some query;
string translatedName = Texts.data[0].name; // this won't work
You should instead add more columns in the database, each for a different language and select the column based on the user language.
Other solution is to have a transaltion mechanism (a custom class for example), where you pass the original database result (say data[0].name) to a query and it returns the translated value for you.

ParseObject queries with relative search parameters

I'm rather new to Parse and Cloud Code, and I'm having trouble writing a certain query script.
I have a table of Salespeople, who have two integers : dailySold and dailyQuota.
The dailySold is reset to 0 each day, and the dailyQuota is defined by upper management.
Now, I'd like to make queries that call out bulks of users. Say, all users which dailySold is below their dailyQuota. In MySQL it would just look like this :
select * from salespeople where dailySold < dailyQuota
But in Parse / CloudCode I have been unable to find something like this. Currently, I'm loading all the entries, and going through them one by one, populating a large array clientside. This feels like the absolutely wrong way of doing it.
And the query.WhereNotEqualTo() function (and their siblings) seem to only be able to compare with static queries.
Does anyone know how to put together a query to optimize this ? I need it to go through thousands of records, and its often only 10-20 results I'm interested in. If nothing else, I'll have to make a cloudcode function that iterates for me serverside, but I still feel like there is some function I should be able to use, to make a more lean query.
You can't compare two columns in a query. You can only compare a key with a provided object. If the dailyQuota is set by upper management, I'm assuming this is the same for all salespeople, or for groups of people. I'd suggest first making a query for the daily quota and then either use
whereKey:matchesKey:inQuery
or just fetch the dailyQuota first and then use that value in the second query.

Indexed databases in Random Access Memory

I'm currently writing a small test web application for a jobs search system.
I have a table Vacancies (the main table to talk about).
I need to make a rapid AJAX update of vacancies (in a suggest list below input control) matched to a user query. Different DBMS provide powerful programming extensions like Free Text Search in Microsoft SQL Server .. but I think that scanning a physical file takes plenty of time. And my idea is based on transfering the whole table Vacancies into RAM, so it, in my view, makes sense since in this case data retrieving demands less time.
So if a client types in a textbox something like "pro" - the suggest list shows up with suggestions:
-product manager
-professional designer
-programmer
-programmer C#
-programmer Java
-property administrator
-provision expert
when a user types another letter "g", the value of a textbox widens to "prog"
and the list is refreshed:
-programmer
-programmer C#
-programmer Java
To make that possible I plan to create a tree index with saved values in nodes, where a vacancy prefix will play a role of the index key and node values are the vacancy names. The index is built and populated only once with data from a data table. See what I mean below:
"pro" -> {
"product manager",
"professional designer",
"programmer",
"programmer C#",
"programmer Java"
"property administrator",
"provision expert"
}
So an index builder must analyze a string list and find the least prefixes of vacancy names.
Then when a builder finds a string with a letter after prior found prefix, it creates a child tree node ("prog") (the count of data values in that node decreases as it is constantly filtered) and adds itself up to the parent node ("pro")
"prog" -> {
"programmer",
"programmer C#",
"programmer Java"}
}
Can you advise me on the types of tree indexes that naturally fit to solve this problem?
What's the best of them by the seek time?
Thanks
This problem was solved years ago, you are recreating Lucene:
For what it's worth the type of tree you want is a Patricia Tree or a Radix Tree. In terms of storing all data in RAM, this is a bad idea because there are other applications that use RAM not just your index. Currently I am ripping out someone's custom database that they thought was a good idea to implement this way and replacing it with a real database solution.

Competitions: Storing an arbitrary number of fields

I'm going to be creating competitions on the current site I'm working on. Each competition is not going to be the same and may have a varying number of input fields that a user must enter to be part of the competition eg.
Competition 1 might just require a firstname
Competition 2 might require a firstname, lastname and email address.
I will also be building a tool to observe these entries so that I can look at each individual entry.
My question is what is the best way to store an arbitrary number of fields? I was thinking of two options, one being to write each entry to a CSV file containing all the entries of the competition, the other being to have a db table with a varchar field in the database that just stores an entire entry as text. Both of these methods seem messy, is there any common practice for this sort of task?
I could in theory create a db table with a column for every possible field, but it won't work when the competition has specific requirements such as "Tell us in 100 words why..." or "Enter your 5 favourite things that.."
ANSWERED:
I have decided to use the method described below where there are multiple generic columns that can be utilized for different purposes per competition.
Initially I was going to use EAV, and I still think it might be slightly more appropriate for this specific scenario. But it is generally recommended against because of it's poor scalability and complicated querying, and I wouldn't want to get into a habit of using it. Both answers worked absolutely fine in my tests.
I think you are right to be cautious about EAV as it will make your code a bit more complex, and it will be a bit more difficult to do ad-hoc queries against the table.
I've seen many enterprise apps simply adopt something like the following schema -
t_Comp_Data
-----------
CompId
Name
Surname
Email
Field1
Field2
Field3
...
Fieldn
In this instance, the generic fields (Field1 etc) mean different things for the different competitions. For ease of querying, you might create a different view for each competition, with the proper field names aliased in.
I'm usually hesitant to use it, but this looks like a good situation for the Entity-attribute-value model if you use a database.
Basically, you have a CompetitionEntry (entity) table with the standard fields which make up every entry (Competition_id, maybe dates, etc), and then a CompetitionEntryAttribute table with CompetitionEntry_id, Attribute and Value.You probably also want another table with template attributes for each competition for creating new entries.
Unfortunately you will only be able to store one datatype, which will likely have to be a large nvarchar.
Another disadvantage is the difficulty to query against EAV databases.
Another option is to create one table per competition (possibly in code as part of the competition creation), but depending on the number of competitions this may be impractcal.

what is the best way to analyze user raw query and detect what who want to search

i am developing a very basic prototype of web search engine and now i want to know what is the best way to analyze user raw query and detect what who want to search. like Google, Bing, Yahoo etc...
an example user raw query is something like this:
Google+Maps+"South+Africa"+Brazil+OR+Italy+OR+Spain+-Argentina+Netherlands
and i want to split this to a generic list of each term(single) like this:
IEnumerable<KeyValuePair<TermType, string>>
<TermType.All, "Google">
<TermType.All, "Maps">
<TermType.Exact, "South">
<TermType.Exact, "Africa">
<TermType.Any, "Brazil">
<TermType.Any, "Italy">
<TermType.Any, "Spain">
<TermType.None, "Argentina">
<TermType.None, "Netherland">
i don't want complete code, i want guidance, solution, tips or anything that's help me to write best for analyze user raw query.
thanks in advance
Don't think in terms of the query string. Think first in terms of the logical search operations you wish to permit, and how your engine will satisfy them.
How each set of logical operations can be translated from one or more query strings then becomes an implementation detail.

Categories

Resources