Searching over multiple types

Petter Klang
Member since: 2008
 

Been checking the documentation for this and I am still having some issues to get it to work.

My solution will have two types, RFPageBase and Document.

I'm currently running the code below but it only gives me RFPageBase pages. I get that I'm only getting this as this is what I'm setting in my searchQuery. But all my tries so fare hasn't resulted in a searchQuery that will include both objects. Anyone got any ideas I can try?

searchQuery = client.Search<RFPageBase>().For(Query)
			.Filter(accessFilter)
			.Filter(pageFilter);

results = searchQuery.Select(x => new FindResult
			{
				Heading = x.PageName,
				Changed = x.Changed,
				Created = x.Created,
				LinkURL = x.LinkURL,
				PreviewText = x.SearchText.AsCropped(200),
				SearchType = x.SearchHitType,
				RFId = x.RFId,
				Tags = x.SearchKeywords != null ? x.SearchKeywords.ToList() : null
			})
			 .IncludeType<FindResult, Document>(x => new FindResult
			 {
				 Heading = x.FileName,
				 Changed = x.Changed,
				 Created = x.Created,
				 LinkURL = x.LinkURL,
				 PreviewText = x.AltText.AsCropped(200),
				 SearchType = x.SearchHitType,
				 RFId = x.RFId,
				 FileExtension = x.FileTypeExtension,
				 FileSize = x.FileSize, 
				 Height = x.Height,
				 Width = x.Width,
				 Photographer = x.Photographer
			 })
			.Skip((PagingPage) * PageSize)
			.Take(PageSize)
			.ApplyBestBets()
			.GetResult();

    

 
#65940 Feb 15, 2013 11:53
  •  

    Hi,

    By removing ".For()" the query will hit all RFPageBase and Documents so that you can verify that you get both types in the result (and not be dependent on specific documents are mathing a query). 

    Regards,
    Henrik

    #65959 Feb 15, 2013 16:59
  • Petter Klang
    Member since: 2008
     

    But if I remove the For() won't it hit all documents in the index as I now don't have a searchterm?

    #65960 Feb 15, 2013 17:03
  •  

    Yes, but only of the specific types you are searching for. Maybe I missunderstood your question but by removing ".For()" you will get a searchQuery that most definitely will result in hits of both types (to verify that you are not passing an unmatching searchQuery). 

    #65961 Feb 15, 2013 17:08
  • Petter Klang
    Member since: 2008
     

    Right well I checked that before. If I change to client.Search<Object>().For(Query) I will get all results I expect (just like I do in the "Explore" in admin). But from this I can only conclude that if I wish to search for both RFPageBase and Documents I would need them both to have the same base class, but that cant be right can it?

     

     

    #65962 Feb 15, 2013 17:12
  •  

    No, the IncludeType should do it for you. Is the pageFilter restricting the Documents from beeing returned?

    #65963 Feb 15, 2013 17:17
  • Petter Klang
    Member since: 2008
     

    Right you are!

     

    Removing the filters gave me what I wanted.... now I just need to fix the filters =)

    Thanks again!

    #65964 Feb 15, 2013 17:21
  • Petter Klang
    Member since: 2008
     

    Been looking at my filter and can't figure out where I'm going wrong.

     

    protected FilterBuilder<RFPageBase> accessFilter { get; set; }
    
    foreach (var role in userRoles)
    {
    	accessFilter = accessFilter.Or(x => x.RolesWithReadAccess().Match(role));
    }

     

    This is how I set it up. I noticed that I didn't have a RolesWithReadAccess() method on my Document object so added one of those but when running it in debug the method never gets called. 

    So I'm wondering will the filter execute over both items types or will it only run on the RFPageBase?

    #65990 Feb 18, 2013 10:23
  •  

    Have you added the method as indexed by configuring the conventions:

    client.Conventions.ForInstancesOf<Document>()
    .IncludeField(x => x.RolesWithReadAccess());

    #65991 Feb 18, 2013 10:50
  • Petter Klang
    Member since: 2008
     

    Reindexing feels like it should work. Got another issue with trying to run the indexing now though so can't test it at the moment.

     

    {"The remote server returned an error: (500) Internal Server Error.\r\nRemoteTransportException[[Burstarr][inet[/10.3.98.11:9300]][index]]; nested: "}

    at EPiServer.Find.Api.Command.GetResponse[TResult](IJsonRequest request)
    at IOCore.CustomAdmin.ScheduledJobs.ReIndexImageVaultFilesJob.Execute() in
    ..\CustomAdmin\ScheduledJobs\ReIndexImageVaultFilesJob.cs:line 76

    The code on line 76 is where I execute the indexing.

     client.Index(fileToIndex);

    is the 10.3.98.11:9300 epis cloud?

    #66030 Feb 18, 2013 17:35
  •  

    We have done some maintainance jobs on our test environment that might have casued the problem. We have completed the job so it is safe for you to try indexing agian.

    #66059 Feb 19, 2013 10:46
  • Petter Klang
    Member since: 2008
     

    Right. Two things.

    1. Would be great if maintainance like this is announced =)

    2. Reindexing pages are working now but the image job is not. It still gives the same error could it be stuck in a bad state? Can I flush that state somehow?

    #66060 Feb 19, 2013 11:06
  • Petter Klang
    Member since: 2008
     

    Been debugging this a bit and the error seems to come from the class
    EPiServer.Find.Connection.JsonRequest.GetResponse()
    It throws the error on line 46. (HttpWebResponse response = (HttpWebResponse) this.webRequest.GetResponse();)
    But on line 45 you have what looks like a logging of sort:
    Trace.Instance.Add(new TraceEvent(this, string.Format("Executing {0} request to {1}.", this.webRequest.Method, this.RequestUri)));
    Where can I find this trace?
    Just setting the regular logging to DEBUG doesn't seem to work.

    #66061 Feb 19, 2013 12:03
  •  

    To catch TraceEvents you need to implement an ITraceListener, for Log4net it will look something like:

    public class TraceListener : ITraceListener
        {
            ILog log = LogManager.GetLogger("MyLogger");
    
            public void Add(ITraceEvent traceEvent)
            {
                var message = new StringBuilder();
                if (HttpContext.Current != null)
                {
                    message.Append("During HTTP request to: ");
                    message.Append(HttpContext.Current.Request.Url);
                    message.AppendLine();
                }
    
                message.Append("Instance ");
                message.Append(traceEvent.Source.TraceId);
                message.Append(" of type ");
                message.Append(traceEvent.Source.GetType());
                message.Append(" reported: ");
                message.Append(traceEvent.Message);
                message.AppendLine();
    
                if (traceEvent.IsError)
                {
                    log.Error(message.ToString());
                }
                else
                {
                    log.Debug(message.ToString());
                }
            }
        }

        

    #66065 Feb 19, 2013 13:14
  •  

    As for your problem. Make sure that if you are passing an attachment to the indexer. Do not pass a null value as it is expected to exist if specified on the object.

    #66066 Feb 19, 2013 13:30