Lucene.net Umbraco order by multiple fields - c#

I am trying to search on multiple fields in Umbraco and order the results by two factors:
Is it a specific type, yes place it on top
Order it by stock
I am using Umbraco 4.9.1.
var Searcher = ExamineManager.Instance.SearchProviderCollection["MySearcher"];
var searchCriteria = Searcher.CreateSearchCriteria();
var results = Searcher.Search(searchCriteria.OrderByDescending("IsAccesoires", "stock").Compile().RawQuery(search));
If I only search on IsAccesoires it works; if I search on both (IsAccesoires and stock") stock ignores the IsAccesoires.

Related

Does Azure Search result guarantee order for * query?

I'd like to manage AzSearch documents (indexed items) by AzSearch C# SDK.
What I try to do is to list up documents by query result (mostly * result) continuously and edit values of them.
To list up query result is as below;
public async Task<IEnumerable<MyIndexModel>> GetListAsync(string query, bool isNext = false)
{
if (string.IsNullOrEmpty(query)) query = "*";
DocumentSearchResult list;
if (!isNext)
{
list = await _indexClient.Documents.SearchAsync(query);
}
else
{
list = await _indexClient.Documents.ContinueSearchAsync(ContinuationToken);
}
ContinuationToken = list.ContinuationToken;
return list.Results.Select(o => o.Document.ToIndexModel());
}
One requirement is to jump to the n-th list of items. Since AzSearch does not provide paging, I'd like to know whether it gives ordered list or not.
If we do not update document count (not index further), does AzSearch give unchanged/ordered list so I can get the same document for jump to 80th list by running ContinueSearchAsync() method 80 times?
Do I have to maintain another lookup table for my requirement?
* is a wildcard query. Documents matching a wildcard query are given the same constant score in ranking because there's no way to measure how close a document is to . Further, order between the same score document is not guaranteed. A document matching '' can be ranked 1st in one response and 7th position in another even when the same query were issued.
In order to get consistent ordering for wildcard queries, I suggest passing in an $orderBy clause, search=*&$orderBy=id asc for example. Azure Search does support paging via $skip and $top. This document provides the guidance.

Sorting on directorySearcher based on two properties in c#

I'm trying to get a sorted SearchResultCollection object based on department, and then by name (both alphabetical). I'm trying to load two properties, but this merely takes the last property specified and sorts it based on that.
My current code is the following:
DirectoryEntry entry = new DirectoryEntry(ConfigurationManager.AppSettings["LDAP"]);
DirectorySearcher search = new DirectorySearcher(entry)
{
SearchScope = SearchScope.Subtree,
Filter = "(&(objectClass=user)(physicalDeliveryOfficeName=Dartmouth))"
};
search.PropertiesToLoad.Add("name");
search.PropertiesToLoad.Add("phone");
search.PropertiesToLoad.Add("email");
search.PropertiesToLoad.Add("department");
search.Sort.Direction = System.DirectoryServices.SortDirection.Ascending;
search.Sort.PropertyName = "department";
search.Sort.PropertyName = "name";
SearchResultCollection result = search.FindAll();
But again, this only sorts by name. I need all users grouped by department, and from there sorted by name.
Cast the SearchResultCollection to an IEnumerable and then sort with a custom IComparer that you develop
var results = search.FindAll().Cast<SearchResult>()
.Sort(/*your IComparer<SearchResult>*/);
Sort the results on client side because server side sorts in AD are resource intensive.
In addition - if you have AD 2000 it doesn't support search on more than one attribute

MongoDB substring product search order by highest match

I'm not so good in Mongodb. That's my first project using this. I'm working on some sort of shop website. We're using C# and newest C# driver for mongodb. I need an idea how to implement my algorithm to filter products based on user's input. Here's how my algorithm works/should work.
User type something like "Blue adidas men spiderman cotton t-shirt"
I split whole phrase into single words so I have "blue", "adidas", "men", "spiderman", "cotton", "t-shirt"
I check each word against retailer, color, category names in my db. So here's how it goes.
"Blue" - oh, it's a color filter let's filter this against proper field in my mongodb document.
"adidas" - ok, it's retailer. Do the same as in point above
"men" - it's a category. Ok so let's search only in this category.
"cotton" - I don't filter by textile. Can't filter by this.
"spiderman" - definetly not a retailer, color etc. Can't filter using this.
"t-shirt" - Ok. It's category name that appears as child category for kids, men, women but since I already have "men" as my category I just go a little bit deeper into my category structure - Now I update my categoryId I want to filter against and it's t-shirt category under men category.
Ok. I parsed few filter params from user input but I still have cotton and spiderman word. And that's where I'm lost.
I would like to not ignore this "spiderman" and "cotton" words. I would like to actually get ALL items from database order by word coverage in its product name so my expected result (ofc with all retailer, color etc filters applied first) are:
products that names contain both "spiderman" and "cotton" products
products that names contain either "spiderman" or "cotton"
How can I do that?
First of all, you can combine multiple filters with using & operator like this:
var builder = Builders<Product>.Filter;
FilterDefinition<Product> filter = builder.Empty;
filter &= builder.Eq("Color", "blue");
filter &= builder.Eq("Retailer", "adidas");
filter &= builder.Eq("Category", "men");
Then, you can use Regex to filter the products the names of which contain any rest words/all rest words.
OR search (the name contains "cotton" OR "spiderman")
var restWords = new string[] { "cotton", "spiderman" };
var orReg = new System.Text.RegularExpressions.Regex(string.Join("|", restWords));
filter &= builder.Regex("Name", BsonRegularExpression.Create(orReg));
List<Product> filteredList = products.Find(filter).ToListAsync().Result;
AND search (the name contains "cotton" AND "spiderman")
foreach (var word in restWords)
{
filter &= builder.Regex("Name", BsonRegularExpression.Create(new System.Text.RegularExpressions.Regex(word)));
}
List<Product> filteredList = products.Find(filter).ToListAsync().Result;

SharePoint Server Search returning documents for a specific client id

I'd like to use the SharePoint Server search and return documents for a specific client id.
The code now returns everything with a wildcard search:
using (ClientContext clientContext = new ClientContext(hostWeb))
{
clientContext.Credentials = new System.Net.NetworkCredential(hostWebAdmin, hostWebPassword, hostWebDomain);
KeywordQuery keywordQuery = new KeywordQuery(clientContext);
var scope = "All Sites";
keywordQuery.QueryText = String.Format("{0} AND Path:\"{1}\" AND Scope:\"{2}\" AND IsDocument:1", searchValue, hostWeb+"PropertyDocuments", scope);
SearchExecutor searchExecutor = new SearchExecutor(clientContext);
ClientResult<ResultTableCollection> results = searchExecutor.ExecuteQuery(keywordQuery);
clientContext.ExecuteQuery();
//foreach (SearchResults s in searchResults)
foreach (var resultRow in results.Value[0].ResultRows)
{
looking at the results of the resultRow - i cannot find a key for client id or client name.
Any suggestions on how to filter by the client id?
thanks.
To get additional fields for you to filter on in your results, you need to take a few steps. First, make sure you have a managed property that is mapped to the crawled property that has your ID and is marked as 'Retrievable' and 'Queryable'. If you don't know how to do that, follow this link Manage the Search Schema. You will have to run a full crawl after updating or adding new managed properties. You can use the managed property directly in your query, but to get it actually returned in your results you need to add it as an additional field to be returned. For example, say your managed property is named ClientID.
int clientId = 5;
keywordQuery.QueryText = String.Format("{0} AND Path:\"{1}\" AND Scope:\"{2}\" AND ClientID:\"{3}\" AND IsDocument:1", searchValue, hostWeb+"PropertyDocuments", scope, clientId);
keywordQuery.SelectProperties.Add("ClientID");
You can add multiple fields this way to return in your results for additional filtering or display purposes.

C# / DirectoryEntry / All Groups / Filtering

I'm messing up with getting a full and usable list of all recursive groups to populate up a dropdownlist control to select a group to administer right within a ASP.net page.
The used Code:
List<string> groups = new List<string>();
using (DirectorySearcher searcher = new DirectorySearcher(dEntry))
{
searcher.Filter = "(objectCategory=group)";
foreach (SearchResult result in searcher.FindAll())
{
string group = result.Path.Substring(result.Path.IndexOf("/CN=")+4);
string formatedResult = group.Substring(0, group.IndexOf(",CN="));
groups.Results.Add(formatedResult);
}
}
The result list is long, containing a bunch of system-groups, which are not needed.
Only specific system-groups should be included in the groups list, like "Administrators" and all "non-system-defined" or "system-related" groups. (Like: Departments, Applicationgroups, etc. defined in the AD-Structure).
Any hint how to do that with DirectoryEntry?
If the 0x1 flag is present in groupType attribute, the group is created by the system.
Can modify the filter to search for:
system groups:
(&(objectCategory=group)(groupType:1.2.840.113556.1.4.803:=1))
non-system groups:
(&(objectCategory=group)(!(groupType:1.2.840.113556.1.4.803:=1)))
I've used the example in the link below with success. I've used it to search usernames in our AD, but it can ofcourse be modified.
AccessingtheActiveDirectoryfromMicrosoftNET

Categories