Get Available Search Indices
I am creating a custom search control that allows specify what content they would like to search (events, news, etc). I would like the user to be able to specify which search index to use for each type of content in the control designer in the Sitefinity backend. How would I retrieve the available defined search indices to put them in a combobox for user selection? I didn't see a way to retrieve them from the SearchManager. Is there another object that manages the search indices or did I miss them on the SearchManager?
Thanks.
Does anyone know how to accomplish this? This is one of the last features of my project which is wrapping up very shortly. I need to be able to allow the user to select which search indices to use for my search functionality. How do I get the available search indices?
Thanks.
Hi Geoff,
You can use the code below to get the active pipes
var providerName = "SearchPublishingProvider";
var pipeTypeName = "SearchIndex";
List<PublishingPipeViewModel> pipesList = new List<PublishingPipeViewModel>();
var manager = PublishingManager.GetManager(providerName);
var query = manager.GetPipeSettings().Where(p => p.PipeName == pipeTypeName);
query = query.Where(p => p.IsActive == true && p.IsInbound == false);
Kind regards,
Ivan Dimitrov
the Telerik team
Thanks, Ivan. That retrieved the search indices for me. Not sure how I would have figured out those strings without being told, since there doesn't appear to be any documentation around this.
This leads me to another question. I'm now attempting to perform a search using a selected index and am not getting any search results. The index is created for events, events exist on the sitefinity backend, and I have reindexed the search index. The events were created using a simple workflow, which required approval before publishing the events. I selected the frontend page I used to create the events as the "Default page where events are published", but am getting no results. I assume the events were actually created through the backend, since that is where the approval/publishing took place.
Which page do I need to select for the "Default page where events are published"?
How would I index events created through the Sitefinity backend?
There's not much to it, but here is my code to perform the search:
/* EventsSearchIndexTitle is a valid string containing a valid title of a search index */
/* query is a string containing part of one of the event titles */
SearchManager searchManager = SearchManager.GetManager(
null
);
IResultSet results = searchManager.Find(EventsSearchIndexTitle, query,
null
);
/* results contains 0 elements */
Hi Geoff,
If you use the public search box and search result control are you getting results? There is a bug related to the search that we found earlier this week and we are going to provide a fix with the internal build.
Greetings,
Ivan Dimitrov
the Telerik team
Ivan, I do get results using the same Search Index with the built in search controls. Do the built in controls use the same API that I am trying to hook into? Assuming this is the case, am I using the API incorrectly?
Thanks.
Ivan,
Do you have more input on this issue? Why does the built in search control work, but my custom search control does not? Are the controls not using the same API? As posted in another thread, the only outstanding tasks on my project currently are awaiting feedback from Telerik in this thread and this thread, so timely resolutions to these issues would be appreciated by both my team and my client.
Thanks.
Hello Geoff,
Can you try to add the following two parameters to the Find method
var IndexCatalogue = "NameOfYourIndex";
var searchQuery = "SearchFor";
var skip =0;
var take = 50;
var searchManager = SearchManager.GetManager(null);
IResultSet result = searchManager.Find(
IndexCatalogue,
searchQuery,
skip,
take
);
All the best,
Ivan Dimitrov
the Telerik team
Adding 'skip' and 'take', as shown in your posted example, still returns 0 results, while the same query returns results using the out of the box search control with the same search index.
For what it's worth, I am using Sitefinity 4.0 SP1 because there are breaking changes in 4.1 and we are unable to upgrade at this point in time. Do you know of any bugs in 4.0 SP1 that would be causing this behavior?
Does your posted code sample return results for a given search index in your environment? Which version of Sitefinity are you testing against?
Thanks.
Hi Geoff,
I am still not able to replicate an issue with the same code.
Best wishes,
Ivan Dimitrov
the Telerik team
Ivan, which version of Sitefinity did you test the code on? I am using Sitefinity 4.0 SP1 because of the breaking changes in 4.1 and we are unable to upgrade at this point in time. Do you know of any bugs in 4.0 SP1 that would be causing this behavior?
Thanks.
Hi Geoff,
I am using Sitefinity 4.1 release.
All the best,
Ivan Dimitrov
the Telerik team
Ivan, I am able to get the previously posted code to work in 4.1 SP1.
Now that I have an IResultSet, I don't see how to retrieve the search results from it.
The .ToArray() extension method throws an IndexOutOfRangeException when called, even though the IResultSet contains 2 results. I'm assuming this is a bug. Is there another way to iterate through the returned list? What type is contained within the collection?
Thanks.
Hi Geoff,
The query returns IResultSet which inherits from IEnumerable<IDocument>. The IResultSet is based on the hits. Inside the IResultSet there is all data for the returned item.
Thanks for the internal datatype and the list of properties available.
I was hoping to display this collection through a RadGrid, but am unable to bind the collection to the grid's datasource. As mentioned before, calling .ToArray() on the collection throws an IndexOutOfRangeException, and binding the IEnumerable collection results in the DataItem being null on the RadGrid.ItemDataBound event.
Here is my code attempting to display the results:
protected
override
void
InitializeControls(GenericContainer container)
grdSearchResults.ItemDataBound +=
new
GridItemEventHandler(grdSearchResults_ItemDataBound);
private
void
SearchEvents(
string
query)
if
(
string
.IsNullOrEmpty(SearchCatalog))
return
;
int
skip = 0;
int
take = 50;
SearchManager searchManager = SearchManager.GetManager(
null
);
IResultSet results = searchManager.Find(SearchCatalog, query, skip, take);
grdSearchResults.DataSource = results;
grdSearchResults.DataBind();
private
void
grdSearchResults_ItemDataBound(
object
sender, GridItemEventArgs e)
IDocument result = e.Item.DataItem
as
IDocument;
// result == null :-(
Label lblTitle = e.Item.FindControl(
"lblTitle"
)
as
Label;
if
(result !=
null
&& lblTitle !=
null
)
lblTitle.Text = result.GetValue(
"Title"
);
Hello Geoff,
Find returns IResultSet. You need to cast the result to List
<
telerik:RadGrid
runat
=
"server"
ID
=
"RadGrid2"
AutoGenerateColumns
=
"true"
Skin
=
"Vista"
EnableViewState
=
"true"
>
</
telerik:RadGrid
>
var IndexCatalogue =
"index1"
;
var skip = 0;
var take = 50;
var searchManager = SearchManager.GetManager(
null
);
IResultSet result = searchManager.Find(
IndexCatalogue,
"ssss"
,
skip,
take
);
this
.RadGrid2.DataSource = result.AsEnumerable().First().Fields.ToList();
this
.RadGrid2.DataBind();
I tried using LINQ a few different ways to bind the grid's datasource.
this
.RadGrid2.DataSource = result.AsEnumerable().First().Fields.ToList();
this
.RadGrid2.DataBind();
this
.RadGrid2.DataSource = result.AsEnumerable().ToList();
this
.RadGrid2.DataBind();
Hi Geoff,
From the fields you can extract all data for the returned item. We return field items that represents the actual content item.
Regards,
Ivan Dimitrov
the Telerik team
Ivan,
Using
var fields = result.AsEnumerable().First().Fields.ToList();
Hi Geoff,
The sample code queries the first item item only. This is an ASP.NET IEnumerable<Type>
For instance you can use MoveNext and .Curent to get the items .
Greetings,
Ivan Dimitrov
the Telerik team
Correct, but I am trying to bind this collection to a RadGrid, so I cannot iterate through the list.
I previously posted this:
this
.RadGrid2.DataSource = result.AsEnumerable().ToList();
this
.RadGrid2.DataBind();