Referencing a PageData object in another object being indexed

Vote:
 

I have a database of employees and many of the employees in the database have corresponding pages in EPiServer. I want to add the PageData to the model of the employee object (called PersonWrapper) being indexed to be able to access the page directly in the result without having to do a lookup for the pagedata object for each search result.


The problem I'm having is that for some properties I was unable to convert them to string. This was however solved by adding a JsonIgnoreAttribute to the properties in the PageTypeBuilder class.
But now I get the following error instead:

Self referencing loop detected for property 'Parent' with type 'EPiServer.Core.PropertyDataCollection'. Path 'PersonPage.Property[0]'. The loop was detected in the member Parent in type EPiServer.Core.PropertyCategory. To correct this you can exclude one of the properties (or otherwise mapped fields) that are causing the loop by modifying the Client class' conventions. You may also modify the serializer to ignore self references. If you require the fields causing the loop to be serialized you may annotate the one of the classes in the loop with [JsonObject(IsReference = true)] or modify the JsonContract for one of the types to use IsReference = true which also can be done by modifying the Client class' conventions.

How can I exclude the CategoryProperty from the PageData object when indexing it and why doesn't the built-in scheduler have the same problem when indexing pages? Can Conventions.ForInstancesOf<PersonWrapper>().ExcludeField(x => x.PersonPage.Category) be used and if so, how?


Another off-topic question: How can I fetch a result from EPiServer find which only gives me object where a certain property is not null?

I'd like to do something like this: Client.CreateFromConfig().Search<PersonWrapper>().Filter(x => x.PersonPage.IsNotNull()).GetResult() but that doesn't work since IsNotNull don't return a querying filter

 

Here is my indexing code:

public static string Execute()
        {
            var persons = RepositoryFactory.GetRepository().GetAllPersons();
            var alreadyAddedIds = new List<int>();
            foreach (var person in persons)
            {
                if (!alreadyAddedIds.Contains(person.Id))
                {
                    try
                    {
                        var personPage = EPiHelper.GetPersonPage(person.Id.ToString(CultureInfo.InvariantCulture));
                        var personWrapper = new PersonWrapper
                        {
                            Id = person.Id,
                            TimeToLive = new TimeSpan(3, 0, 0),
                            Person = person,
                            PersonPage = personPage as PersonPage
                        };
                        Client.CreateFromConfig().Index(personWrapper);
                        alreadyAddedIds.Add(person.Id);
                    }
                    catch
                    {
                        // TODO: handle exception
                    }
                }
            }
            return string.Format("{0}/{1} persons added to the index",alreadyAddedIds.Count, persons.Count());
        }
And this is my model:
    public class PersonWrapper:SearchObjectBase
    {
        public Person Person { get; set; }
        public PersonPage PersonPage { get; set; }
    }
    
#81293
Feb 13, 2014 12:31
Vote:
 

Hi!

Whenever working with EPiServer data, use SearchClient.Instance instead of Client.CreateFromConfig. SearchClient.Instance contains the neccesary conventions used for handling IContent.

However, I would recommend indexing the page reference instead of the page itself. Doing a Get(..) later on to fetch the actual page is not a costly operation. This is actually done in the standard .GetContentResult() method.

I recommend that you check this out:

http://world.episerver.com/Documentation/Items/Developers-Guide/EPiServer-Find1/75/Integration/EPiServer-75-CMS/GetContentResult-and-GetFilesResult/

If you need to filter on null values, you can use .Exists() to do that.

Also, if this is a large number of people, consider indexing your results in bulks: 

http://world.episerver.com/Blogs/Per-Magne-Skuseth/Dates/2013/5/EPiServer-Find-Bulks-please/

#81438
Feb 17, 2014 13:50
Vote:
 

Thank you!

#81447
Feb 17, 2014 15:58
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* 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.