I have tried the examle in the link you posted. I understand what it wants to do but I can't manage to do it :)
The problem I have is that ApplicationBase is deprecated.
As recommended by umbraco documentation I should use interface IApplicationEventHandler instead.
The error I get with this is "No overload for 'SetSiteSearchFields' matches delegate 'System.Eventhandler'".
This feels like a minor error but whatever I try I can't manage to fix it.
Here is the code in my class:
public class CmsEvents : IApplicationEventHandler
{
public void OnApplicationStarted(UmbracoApplicationBase httpApplicationBase, Umbraco.Core.ApplicationContext applicationContext)
{
var indexerSite = ExamineManager.Instance.IndexProviderCollection["MySearchIndexer"];
indexerSite.GatheringNodeData += new EventHandler(SetSiteSearchFields);
}
public void OnApplicationStarting(UmbracoApplicationBase httpApplicationBase, Umbraco.Core.ApplicationContext applicationContext) { }
public void OnApplicationInitialized(UmbracoApplicationBase httpApplicationBase, Umbraco.Core.ApplicationContext applicationContext) { }
//modifies the index field for the path variable, so that it can be searched properly
void SetSiteSearchFields(object sender, IndexingNodeDataEventArgs e)
{
//grab the current data from the Fields collection
var path = e.Fields["path"];
//let's get rid of those commas!
path = path.Replace(",", " ");
//add as new field, as path seems to be a reserved word in Lucene
e.Fields.Add("searchPath", path);
}
}
It's not multiple sites in different languages, it's just multiple sites in one database :)
So the index should be the same for all sites, i just need to contain the search for the current site I'm at.
It feels like I'm very close to a solution where I get the id of the root node of the current site I'm at and then restrict search results to only show if it contains that id in "path".
The problem I have now is that I have a method that I want to pass as a delegate to the examine event "GatheringNodeData" so that I can get rid of the commas in the path-string to be able to search for the id.
I've followed the link that Jivan Thapa posted above. See my second answer to his post to see the code.
public class CmsEvents : ApplicationEventHandler
{
public void ApplicationStarted(UmbracoApplicationBase httpApplicationBase, Umbraco.Core.ApplicationContext applicationContext)
{
var indexerSite = ExamineManager.Instance.IndexProviderCollection["MySearchIndexer"];
indexerSite.GatheringNodeData += SetSiteSearchFields;
}
public void OnApplicationStarting(UmbracoApplicationBase httpApplicationBase, Umbraco.Core.ApplicationContext applicationContext) { }
public void OnApplicationInitialized(UmbracoApplicationBase httpApplicationBase, Umbraco.Core.ApplicationContext applicationContext) { }
//modifies the index field for the path variable, so that it can be searched properly
void SetSiteSearchFields(object sender, IndexingNodeDataEventArgs e)
{
//grab the current data from the Fields collection
var path = e.Fields["path"];
//let's get rid of those commas!
path = path.Replace(",", " ");
//add as new field, as path seems to be a reserved word in Lucene
e.Fields.Add("searchPath", path);
}
}
I have a breakpoint that should trigger when "ApplicationStarted()" is run, but this never happens. This means that the searchpatch is never added to the index in the way it needs to be searchable.
The controller is looking like this:
var searcher = ExamineManager.Instance.SearchProviderCollection["MySearchSearcher"];
var criteria = searcher.CreateSearchCriteria(UmbracoExamine.IndexTypes.Content);
Examine.SearchCriteria.IBooleanOperation filter = null;
//search on main fields
filter = criteria.GroupedOr(new string[] { "nodeName" }, search);
filter = filter.And().Field("searchPath", parentId);
//don't show hidden pages
filter
.Not()
.Field("umbracoNaviHide", "1");
var resultsTemp = searcher.Search(filter.Compile());
////Fetching our SearchProvider by giving it the name of our searchprovider
//var Searcher = Examine.ExamineManager.Instance.SearchProviderCollection["MySearchSearcher"];
//searchResults = Searcher.Search(search, true).OrderByDescending(x => x.Score).TakeWhile(x => x.Score > 0.05f);
model = new SearchModel(resultsTemp);
The OnApplicationStarted() method is now triggering as it should. I hade to change the inheritance from "ApplicationEventHandler" to interface "IApplicationEventHandler". Don't know why but it works, if anyone knows why please edjucate me :)
Now to the next problem:
I dont get any searchresults what so ever when I include this line:
void SetSiteSearchFields(object sender, IndexingNodeDataEventArgs e)
{
//grab the current data from the Fields collection
var path = e.Fields["path"];
//let's get rid of those commas!
path = path.Replace(",", " ");
//add as new field, as path seems to be a reserved word in Lucene
e.Fields.Add("searchPath", path);
}
would make it possible to search on the field "searchPath", but it do not seem to work.
I have implemented something similar to this and used multiple indexes as stated above. You'll need to replicate the ExamineIndexProviders, ExamineSearchProviders and IndexSets, each with their own related names. Then within the Index Set you can set the parent Id to the root of the specific website that you want to search.
<IndexSet SetName="IndexSetName" IndexPath="~/App_Data/TEMP/ExamineIndexes/SiteSearch/NameOfIndex" IndexParentId="ParentNodeIdGoesHere">
<IncludeNodeTypes>
<!-- add node types to include -->
</IncludeNodeTypes>
<ExcludeNodeTypes />
</IndexSet>
If you store the name of the index in a property at the root of each site, you can then easily search the index for that site based on the value stored in the property. You could add a default index as a fallback in case the property value is empty.
I would guess that this is better for performance than using just one index and filtering in code, as each index will be smaller and specific to the site in question. But I haven't done any performance testing to verify this.
where "rootId" is a string with the id of the rootNode, I get 0 results.
I've deleted the TEMP folder in AppData several times. I've republished the site several times. I've tried with ExternalIndexer/ExternalSearcher. I've tried with custom Indexer/Searcher. Still no luck as soon as I add the line to search for "searchPath".
This makes me come to the conclution that it's something wrong with the delegate i pass to the "GatheringNodeData" event. It's not adding the new field "searchPath" it seems.
The event "OnApplicationStartup" triggers and adds the method "SetSiteSearchFields" to the "GatheringNodeData", just as it should. Still, not working.
Im using umbraco 7.2 and develops in a local environment.
This is getting a bit frustrating, i'm very glad that you guys try to help me out as much as you do :)
Could you stop ApplicationPool, Website on IIS, and Delete "Appdata/Temp" folder and "Appdata/umbraco.config" file ?
And restart IIS, again?
if you still have a problem.
Download the software "luke.net" and Install. Browse your Appdata/temp/ExamineIndexes/YourIndexDirectory/Index"
And varify that the field called "searchPath" is exist. You will see lots of field like "nodeName", "path" , "_path" etc
There is no folder for my Index in Appdata/temp/ExamineIndexes/ after I deleted it. It seems to not recreate it when I run the project. The other Indexes are there, External, Internal and InternalMember.
There is a folder in Appdata/ExaminesIndexes that is named after my index, "MySearch". When I check that index with Luke there is no field called "searchPath"
I don't really know what the solution was but i believe it has something to do with me publishing the entire site before, nothing happened. When I just now published the sites one at a time it just.. works.
:D
Big thanks for all help from everyone, especial Jivan Thapa. You really saved my day, I owe you at least one beer :)
Examine for multiple sites
Hi,
I have multiple sites running on one database. When I search with examine I get results from all of the sites that is in the database.
How do I narrow down the search so that it only searches for the current site Im at?
You need to scope your search results by "root" id of the website.
it's an old post but it may solve your issue. http://www.attackmonkey.co.uk/blog/2011/12/limiting-an-examine-search-to-the-current-site
Thanks for your answer, I will check the link :)
I have tried the examle in the link you posted. I understand what it wants to do but I can't manage to do it :)
The problem I have is that ApplicationBase is deprecated.
As recommended by umbraco documentation I should use interface IApplicationEventHandler instead.
The error I get with this is "No overload for 'SetSiteSearchFields' matches delegate 'System.Eventhandler'".
This feels like a minor error but whatever I try I can't manage to fix it.
Here is the code in my class:
On that post checkout commit from stephan regarding multi site in different languages.
Ideally if different languages then create different indexes so that you can use different analysers which is what is ideally required.
Regards
Ismail
It's not multiple sites in different languages, it's just multiple sites in one database :)
So the index should be the same for all sites, i just need to contain the search for the current site I'm at.
It feels like I'm very close to a solution where I get the id of the root node of the current site I'm at and then restrict search results to only show if it contains that id in "path".
The problem I have now is that I have a method that I want to pass as a delegate to the examine event "GatheringNodeData" so that I can get rid of the commas in the path-string to be able to search for the id.
I've followed the link that Jivan Thapa posted above. See my second answer to his post to see the code.
This is the problem i think:
I have a breakpoint that should trigger when "ApplicationStarted()" is run, but this never happens. This means that the searchpatch is never added to the index in the way it needs to be searchable.
The controller is looking like this:
And here is the indexSet:
And here is the settings:
What I'm I missing? :)
Me again.
The OnApplicationStarted() method is now triggering as it should. I hade to change the inheritance from "ApplicationEventHandler" to interface "IApplicationEventHandler". Don't know why but it works, if anyone knows why please edjucate me :)
Now to the next problem:
I dont get any searchresults what so ever when I include this line:
If I comment that out I get results. The full filter looks like this (simplified for testing):
I thought that this method:
would make it possible to search on the field "searchPath", but it do not seem to work.
I have implemented something similar to this and used multiple indexes as stated above. You'll need to replicate the ExamineIndexProviders, ExamineSearchProviders and IndexSets, each with their own related names. Then within the Index Set you can set the parent Id to the root of the specific website that you want to search.
If you store the name of the index in a property at the root of each site, you can then easily search the index for that site based on the value stored in the property. You could add a default index as a fallback in case the property value is empty.
I would guess that this is better for performance than using just one index and filtering in code, as each index will be smaller and specific to the site in question. But I haven't done any performance testing to verify this.
It sounds very good and I will try it out. Thanks! :)
To be sure , remember to delete the folder "App_data/temp". and Let the Umbraco rebuild the index again. And publish the content.
Here is a demo using "ExternalSearcher" .
http://screencast.com/t/qAgELMsZl
Really good video, thanks alot! :)
But... I did all the steps, several times. Still, it does not work.
As soon as a add this line:
where "rootId" is a string with the id of the rootNode, I get 0 results.
I've deleted the TEMP folder in AppData several times. I've republished the site several times. I've tried with ExternalIndexer/ExternalSearcher. I've tried with custom Indexer/Searcher. Still no luck as soon as I add the line to search for "searchPath".
This makes me come to the conclution that it's something wrong with the delegate i pass to the "GatheringNodeData" event. It's not adding the new field "searchPath" it seems.
The event "OnApplicationStartup" triggers and adds the method "SetSiteSearchFields" to the "GatheringNodeData", just as it should. Still, not working.
Im using umbraco 7.2 and develops in a local environment.
This is getting a bit frustrating, i'm very glad that you guys try to help me out as much as you do :)
Could you stop ApplicationPool, Website on IIS, and Delete "Appdata/Temp" folder and "Appdata/umbraco.config" file ?
And restart IIS, again?
if you still have a problem.
Download the software "luke.net" and Install. Browse your Appdata/temp/ExamineIndexes/YourIndexDirectory/Index" And varify that the field called "searchPath" is exist. You will see lots of field like "nodeName", "path" , "_path" etc
https://luke.codeplex.com/releases/view/82190
There is no folder for my Index in Appdata/temp/ExamineIndexes/ after I deleted it. It seems to not recreate it when I run the project. The other Indexes are there, External, Internal and InternalMember.
There is a folder in Appdata/ExaminesIndexes that is named after my index, "MySearch". When I check that index with Luke there is no field called "searchPath"
To re-create the index, publish some content in the back office that you expect to be indexed, then it will be created and rebuilt.
Also delete "app data/ temp/umbraco.config" file
If you cannot see "searchPath" on Luke, You will get 0 results because there is not data for "searchPath".
Could you share your ExamineSettings.config and ExamineIndex.config?
And Could you do POC based on my video on your computer ? on a complete new project with new umbraco installation?
ExamineSettings.config:
ExamineIndex.config
Finally it's working!
I don't really know what the solution was but i believe it has something to do with me publishing the entire site before, nothing happened. When I just now published the sites one at a time it just.. works.
:D
Big thanks for all help from everyone, especial Jivan Thapa. You really saved my day, I owe you at least one beer :)
is working on a reply...