Episerver Lucene Search Results Issue

Vote:
 

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.

#175334
Feb 16, 2017 18:02
Vote:
 

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

#175335
Edited, Feb 16, 2017 19:01
Vote:
 
#175339
Feb 16, 2017 19:07
Vote:
 

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.

#175343
Feb 16, 2017 21:16
Vote:
 

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

#175344
Feb 16, 2017 21:41
Vote:
 

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.

#175346
Feb 16, 2017 22:09
Vote:
 

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

#175348
Feb 16, 2017 23:08
Vote:
 

Yes John. I do have Base Page Type that all pages Inherit from..

Thanks,

Tilak Muvva.

#175389
Feb 17, 2017 19:09
Vote:
 

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: 

  1. Add the SearchText field to your base page class and create the init module exactly like it is described by Jerone. In the init module example code provided, on line 17, change StandardPage to the name of your base type class. On line 24, change page.MainContentArea to the name of your ContentArea on the base class that contains the blocks you want to get text from to search. The rest of the code should be fine to pull over as-is. Initilization Module classes are typically saved in Business/Initilization. 
  2. Remember to go through your block properties and add the attribute [Searchable] on the fields you want to get indexed.
  3. Once is is done, build your project, then log in and re-publish the pages that contain the blocks.

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

#175399
Edited, Feb 20, 2017 4:02
Vote:
 

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.

#175490
Feb 21, 2017 22:09
Vote:
 

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

#175494
Feb 22, 2017 0:02
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.