Fastest way to get the properties of umbraco documents - lucene

I am working on search functionality for a website designed through umbraco. I am using Examine to fetch the search results. Here is my code:
var Searcher = ExamineManager.Instance.SearchProviderCollection["ExternalSearcher"];
var searchCriteria = Searcher.CreateSearchCriteria(BooleanOperation.Or);
var query = searchCriteria.Field("tags", searchTerm.Fuzzy(0.5f)).Compile();
var searchResults = Searcher.Search(query);
With this method i can only get the nodes in which the search term belongs.But I want to directly fetch the whole value from the property.
I want to know what is the fastest way to fetch all the values from the same property in all the nodes.

I have finally managed to get the values directly from the property.This is the code I have used:
List<string> nodesList = new List<string>();
var Searcher = ExamineManager.Instance.SearchProviderCollection["ExternalSearcher"];
var searchCriteria = Searcher.CreateSearchCriteria(BooleanOperation.Or);
var query = searchCriteria.Field("tags", queryString.Fuzzy(0.5f)).Compile();
var searchResults = Searcher.Search(query);
foreach (var item in searchResults)
{
string paths = ((Examine.SearchResult)item).Fields["tags"];
nodesList.Add(paths);
}
using ((Examine.SearchResult)item).Fields["tags"] gets the property value directly.

If you want to costumize your search you need to define a new index set with the properties that you actually want to search on the /config/examineIndex.config file.
Quite well explained in this post.

Related

Renaming models in database with existing data when using RavenDb

Is there any 'easy' way to rename models in RavenDb when the database already has existing data? I have various models which were originally created in another language, and now I would like to rename them to English as the codebase is becoming quite unmaintainable. If I just rename them, then the data won't be loaded because the properties don't match anymore.
I would like the system to automatically do it on first load. Is there any best way how to approach this? My solution would be:
Check if a document exists to determine if the upgrade has been done or not
If upgrade has not been done, execute patch scripts to update fields
Update document to know that the upgrade has been done
I'd recommend you create new documents from the old documents.
This can be done pretty easily using patching via docStore.UpdateByIndex.
Suppose I had an old type name, Foo, and wanted to rename it to the new type name, Bar. And I wanted all the IDs to change from Foos/123 to Bars/123.
It would look something like this:
var patchScript = #"
// Copy all the properties from the old document
var newDoc = {};
for (var prop in this) {
if (prop !== '#metadata') {
newDoc[prop] = this[prop];
}
}
// Create the metadata.
var meta = {};
meta['Raven-Entity-Name'] = newCollection;
meta['Raven-Clr-Type'] = newType;
// Store the new document.
var newId = __document_id.replace(oldCollection, newCollection);
PutDocument(newId, newDoc, meta);
";
var oldCollection = "Foos";
var newCollection = "Bars";
var newType = "KarlCassar.Bar, KarlCassar"; // Where KarlCassar is your assembly name.
var query = new IndexQuery { Query = $"Tag:{oldCollection}" };
var options = new BulkOperationOptions { AllowStale = false };
var patch = new ScriptedPatchRequest
{
Script = patchScript,
Values = new Dictionary<string, object>
{
{ nameof(oldCollection), oldCollection },
{ nameof(newCollection), newCollection },
{ nameof(newType), newType }
}
};
var patchOperation = docStore.DatabaseCommands.UpdateByIndex("Raven/DocumentsByEntityName", query, patch, options);
patchOperation.WaitForCompletion();
Run that code once at startup, and then your app will be able to work with the new name entities. Your old entities are still around - those can be safely deleted via the Studio.

Ravendb retrieve all documents in collection for reporting

I need to retrieve all documents from a collection to dump it to an Excel file.
Using this seems to work
var luceneQuery = Session.Advanced.LuceneQuery<Test.ReduceResult>("Test/ByTestData");
var enumerator = Session.Advanced.Stream(luceneQuery);
var obj = new List<Test.ReduceResult>();
while (enumerator.MoveNext())
{
obj.Add(enumerator.Current.Document);
}
This gives me all the results in the index.
But instead of index I want to retrieve all the documents in a collection (as the index does not contain all the information stored in the document).
How can this be done?
Change your query to be:
var luceneQuery = Session.Advanced.LuceneQuery<Test.ReduceResult>("Raven/DocumentsByEntityName")
.WhereEquals("Tag", "Customers");
This will give you all customers.

Searching for href values with Lucene (Examine in Umbraco)?

I want to search for a href value with lucene/examine - more precise the 'locallink' value. Examine is straight out-of-the-box standard config.
I have the following snippet which does not return any results;
string searchQuery = "localLink:" + id;
UmbracoHelper helper = new UmbracoHelper(UmbracoContext.Current);
foreach (var result in helper.Search(searchQuery, false))
{
// Do something
}
Upon inspection of the index via Developer > Examine Management (in Umbraco backend), I can see that the index does contain the value I am trying to search for but under a "_Raw" property. So I guess the question is, how I can make my search, search in these fields also?
You made search with UmbracoHelper.
Try to use Examine Searcher as described in docs :
var searcher = ExamineManager.Instance.SearchProviderCollection["WebsiteSearcher"];
var searchCriteria = searcher.CreateSearchCriteria(BooleanOperation.Or);
var searchResults = searcher.Search(query);
http://our.umbraco.org/documentation/Reference/Searching/Examine/
http://umbraco.com/follow-us/blog-archive/2011/9/16/examining-examine.aspx

NHibernate CreateSqlQuery() result to an ObservableCollection

I've the following:
using (ISession session = Config.SessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
// This is a System.Collections.ArrayList,contains all my records returned from the session
var list = session.CreateSQLQuery(selectQuery).List();
// I want to put these records in an ObservableCollection of a specific Type
// Something like htis:
MyCollection = new ObservableCollection<MyType>(list);
}
}
This is not working and casting isn't an option here. Is there any way to put my retrurned list to the ObservableCollection?
I've got my ObservableCollection filled by using the following:
var query = session.CreateSQLQuery(selectQuery).AddEntity(typeof(MyType));
myObservableCollection = new ObservableCollection<MyType>(query.List<MyType>());
The List() returns ArrayList. Each value in ArrayList has some value which is type of object.
It can not be converted into directly any specific class. so create a mapping file then only you can get list of your required object.

Time out retrieving items from list

I have a problem retrieving items from a fairly large list. I can quickly and easily retrieve items from a small list with more or less 50 items, but when I try to retrieve items from a list containing more or less 4600 items, the sqlsever.exe process spikes for the duration of the request, but the items are never retrieved. If have set up the web applications throttling settings, so it can’t be that which is causing the problem. Here is the code that I originally used to retrieve the items. There is really nothing special to it.
using (SPSite site = new SPSite(siteUrl))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists[uid.ToString()];
SPListItemCollection itemCollection = list.Items;
foreach (SPListItem i in itemCollection) //This is where the code stops responding
{
//Use list items
}
}
}
After that didn’t work, I tried a couple of other methods to retrieve the items from the list. Here is the code:
SPList list = web.Lists[uid.ToString()];
SPQuery query = new SPQuery();
query.Query = "";
query.QueryThrottleMode = SPQueryThrottleOption.Override;
SPListItemCollection itemCollection = list.GetItems(query);
//The code stops here
//I added this part for interest sake, i wanted to if it was the looping that caused the problem
//It seems the when you try to access properties of the item collection that the problem occurs
int itemCount = itemCollection.Count;
foreach (SPListItem i in itemCollection)
{
//Use list items
}
I also tried:
SPList list = web.Lists[uid.ToString()];
SPListItemCollectionPosition pos;
DataTable dt = list.GetDataTable(new SPQuery(), SPListGetDataTableOptions.None, out pos); //The code stops responding here
foreach (DataRow i in dt.Rows)
{
//Use data rows
}
Does anyone know what could be causing this problem?
Thank you in advance!
After a very long struggle we found a solution.
We found this post:
http://trycatch.be/blogs/tom/archive/2009/04/22/never-turn-off-quot-auto-create-amp-auto-update-statistics-quot.aspx
We tested it and it worked!!!
So all we had to do was switch "Auto create statistics" and "Auto update statistics" to true, and to problem was solved
Thanks for all the replys
You'll kill your server if you always try to retrieve all items either through list.Items, list.GetItems(query) (with an empty query).
You need to define a relevant query and specify the amount of results you want to retrieve through the RowLimit property of your SPQuery
SPQuery query = new SPQuery();
query.Query = "<OrderBy><FieldRef Name='Title' /></OrderBy>"; // any relevant query here
query.RowLimit = 50;
Failing to do so will load all the items in memory prior to any other operation. You will probably kill your application pool available memory or your sql server memory when it will try to load all these data !
Hope that helped.
Try to get data using CAML query.
Once you have data you can put that in SPQuery.
Try to load the items not all at the same time. You can load them bulk wise (page wise) with the help of SPQuery.ListItemCollectionPosition (http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spquery.listitemcollectionposition.aspx).