Hi Tilak,
I am pretty sure that the built-in Lucene search does not index blocks by default. This may be the cause of your issue. You will need to write some custom code to get the blocks indexed. There may be a post somewhere on these forums that goes over how to do it. Hope this helps!
-John
I found this blog post which may also help:
https://jstemerdink.wordpress.com/2014/04/05/indexing-blocks-with-episerver-search/
-John
Hi John,
Thanks for the reply...
But I am getting the results displayed.. If It makes sense to show the issue.. here is the site I am referring to - http://www.healthynursehealthynation.org/
The search keyword I am using is "Healthy Nation"..
I am pretty new to Episerver.. so any input and solution is highly appreciated..
Thank you,
Tilak Muvva.
Hi Tilak,
I see what you are talking about. Are those blocks in a content area on a page? The thing with blocks is that there is no direct URL to one. You would want to link to the page that contains them. The approach in the article I posted above seems like it would be a solution for what you need. The gist of it is that when a page containing the blocks is published, it loops through the blocks and adds the searchable fields to a string field on the page type and indexes them. Then, the search results point to the page and not the block.
The weird thing is that it is even indexing the block in the first place. I doubt that you want a link title like: Resource Block - Become a Sponsor. The title and link should be generated from the page that contains the block.
-John
John,
you are exactly right. Even I was thinking in the same approach. Instead of getting the title of the block, If we get the title of the page containing the block, the issue might be resolved.
But I am not sure how to and where to start.
I have a code here for search and for the view.. Can you help me resolve the issue?
ViewModel code
public void Search(string q)
{
var culture = ContentLanguage.PreferredCulture.Name;
SearchResult = new List<IndexResponseItem>();
var fieldQuery = new EPiServer.Search.Queries.Lucene.FieldQuery(q);
var fieldQueryResult = SearchHandler.Instance.GetSearchResults(fieldQuery, 1, 40)
.IndexResponseItems
.Where(x =>
(x.Culture.Equals(culture) || string.IsNullOrEmpty(x.Culture)))
.ToList();
SearchResult.AddRange(fieldQueryResult);
}
View Code
<div class="row">
<div class="wow fadeInLeft">
@foreach (var item in Model.SearchResult)
{
<div class="listResult">
<h3><a href="@item.GetExternalUrl()">@item.Title</a></h3>
<p>@item.DataUri</p>
<p>@item.DisplayText.TruncateAtWord(20)</p>
<hr />
</div>
}
</div>
</div>
Extension Method
public static Uri GetExternalUrl(this IndexResponseItem item)
{
try
{
UrlBuilder url = new UrlBuilder(item.Uri);
EPiServer.Global.UrlRewriteProvider.ConvertToExternal(url, item, System.Text.Encoding.UTF8);
return url.Uri;
}
catch (Exception)
{
return default(Uri);
}
}
Thanks in advance for the help..
Thanks,
Tilak Muvva.
Hi Tilak,
What does your page type model that has the ContentArea with the blocks look like? It would be ideal if you had a base page type that has the ContentArea that all pages inherit from. Let me know.
Thanks!
John
Yes John. I do have Base Page Type that all pages Inherit from..
Thanks,
Tilak Muvva.
Hi Tilak,
Great, so I think that the approach in the article that Jerone wrote should work. There is also something we can do in the view model so that the actual blocks will not get searched like what is currently happening. Here is what you can try:
In your view model, try this as your Search funtion:
public void Search(string q) { var culture = ContentLanguage.PreferredCulture.Name; SearchResult = new List<IndexResponseItem>(); var query = new GroupQuery(LuceneOperator.AND); // Only search for pages query.QueryExpressions.Add(new ContentQuery<PageData>()); // Search for keywords in any of the fields specified below (OR condition) var keywordsQuery = new GroupQuery(LuceneOperator.OR); // Search in default field keywordsQuery.QueryExpressions.Add(new FieldQuery(q)); query.QueryExpressions.Add(keywordsQuery); // The access control list query will remove any pages the user doesn't have read access to var accessQuery = new AccessControlListQuery(); accessQuery.AddAclForUser(PrincipalInfo.Current, HttpContext.Current); query.QueryExpressions.Add(keywordsQuery); var fieldQueryResult = SearchHandler.Instance.GetSearchResults(query, 1, 40) .IndexResponseItems .Where(x => (x.Culture.Equals(culture) || string.IsNullOrEmpty(x.Culture))) .ToList(); SearchResult.AddRange(fieldQueryResult); }
Let me know how it goes!
-John
Thank you John.
I tried to implement Jerone's Article. But, My baseclass does not have any Content Area. So.. Weird right?
So I tried to implement the other option, modified the View Model and now I get only Page data in search results.
Thanks a lot for your help...
Thanks,
Tilak Muvva.
Hi Tilak,
You could maybe just move the content area to your base class, although, I couldn't say for sure unless I could see the structure of all your page types. The base class is really for any properties that will be shared between multiple types. You could also have multiple base classes too. Basically, if you take the page type that has the content area with the blocks that were getting indexed, move the content area from there to the base class, then inherit from the base class, it should work. Hope this helps!
-John
Hello All,
I am using Episerver Search (Lucene) feature and able to get the search results.
I am displaying the Indexresponse Item Title and generating the link url from GetExternalUrl function as mentioned in the AlloyTraining Site.
However I am getting 404 for some results as they are the blocks. The links to the page titles works perfectly fine.
How to solve this issue. Any help would be greatly appreciated.
Thanks,
Tilak Muvva.