Concept Search with optimizely.graph sdk

Vote:
 

Im evaluating the optimizely.graph.client ... version 1.2, Optimizely.ContentGraph.Cms 3.11, CMS 12.31.1

How do i perform a search with GraphQueryBuilder on ALL IContent, and i want to map the result to our SiteBasePage... Is this even possible?

Something like this:

                var query = _contentGraphClient
                .OperationName("My_Query")
                .ForType<SiteBasePage>()
                //.ForType<ProductPage>()
                .Search(searchKeyword)
                .Fields(_ => _.Name,/* _ => _.Url,*/ _ => _.MetaDescription)
                //.Facet(_ => _.ContentType)
                .Total();

                var result = await query.GetResultAsync();
                string res = result.ToJson(); //this one results in showing items with name and metadescription, nothing more. 
                foreach (var item in result.GetContent<SiteBasePage>().Hits) //dont work, cant map, to any IContent Models... 


But i get

Cannot query field \"SiteBasePage\" on type \"Query\

also

_.Url and _.ContentType does not exists

I don't get the concept yet, Is not compat with IContent?

Should i  only use Custom GraphModels?

#332137
Oct 29, 2024 13:41
Vote:
 

Hi,

I guess your SiteBasePage is an abstract class and it not exist on our Graph server mapping so you can not query for an inexist type. I'm not really work on GraphQL project but as i understand by default the indexing job will only push mapping for concrete classes neither abstract nor interface unless you update the mapping by API.

Should i  only use Custom GraphModels?

Not require but i highly suggest to use Custom GraphModels because it shows exactly which types and fields had indexed to Graph server. You can download our client tool at https://nuget.optimizely.com/package/?id=Optimizely.Graph.Client.Tools for generate the indexed models to your project by just few commands.

I don't get the concept yet, Is not compat with IContent?

Once your Graph models has been generated, you should see the Content type in the models and it should be parent of all content types as IContent. Content is implemented from IContent, of course.

Example:

            var query = _client
                .OperationName("Sample_Query")
                    .ForType<ProxyModels.Content>()
                    .Where(x=> x.ExistingLanguages().Name.Eq("en"))
                    .Skip(0)
                    .Limit(10)
                    .Fields(x => x.Name, x => x.Url, x=> x.ContentType)
                    .Total()
                    .InlineFragment<ProxyModels.ArticlePage>(x => x.MetaDescription, x => x.MetaTitle)
                    .Search(q)
                    .Facet(x => x.ContentType.FacetFilters(t))
                    .ToQuery()
                .BuildQueries();

Please take a quick look at https://docs.developers.optimizely.com/platform-optimizely/v1.4.0-optimizely-graph/docs/introduction-optimizely-graph for more details of concept.

#332438
Nov 05, 2024 1:48
Vote:
 

Thank you Manh! 

I made the first mile! 

Can you guidance me on next thing... 

How do handle ContentAreas? we have ImageData in such area, how to retrieve that? 

//following is not working
.InlineFragment<Optimizely.ContentGraph.ProxyModels.ProductPage>(x => x.MetaDescription, x => x.Title, b => b.ImageArea)

#332747
Nov 12, 2024 14:12
Vote:
 

Hi Luc Gosso,

Basically, select an object is not supported in GraphQL server, select properties that you need instead. In your case ImageArea is an object so it needs you to specify properties. For ex:

.InlineFragment<Optimizely.ContentGraph.ProxyModels.ProductPage>(_ => _.MetaDescription, _ => _.Title, _ => _.ImageArea.Name, _ => _.ImageArea.Url)

You can create a fragment on type of ImageArea for reuseable purpose.

var imageAreaFragment = new FragmentBuilder<Optimizely.ContentGraph.ProxyModels.ProductPage>("imageAreaFrag").Fields(_=>_.ImageArea.Name, _=>_.ImageArea.Url);

Then add fragment into your query:

graphQuery.AddFragments(imageAreaFragment);

It returns the same data as InlineFragment but can reuseable for another query. Another benefit is that you can use recursive directive in fragment builder which is not availble for InlineFragment.

#332804
Nov 13, 2024 4:58
Vote:
 

Thank you,

ImageArea is of type IEnumerable<ContentAreaItemModelSearch>, so

_=>_.ImageArea.Url //not possible

so i tried to use Linq but:

_.ImageArea.First().ContentLink.Url

errors: Cannot query field \"First\" on type \"ContentAreaItemModelSearch\".

What am i missing?

#332809
Nov 13, 2024 9:47
Vote:
 

Hi,

The easiest way for selecting properties of IEnumerable type is create extension class, by this way you can use for selecting fields, faceting, and filtering.

public static class GraphModelsExtension
{
      public static ContentAreaItemModelSearch ImageArea(this IEnumerable<ContentAreaItemModelSearch> image)
      {
          return null;
      }
}

Now you can write your fragment query with ImageArea() method instead of IEnumerable property:

.InlineFragment<Optimizely.ContentGraph.ProxyModels.ProductPage>(_ => _.MetaDescription, _ => _.Title, _ => _.ImageArea().Name, _ => _.ImageArea().Url)

You can find more details for dealing with IEnumerable at https://docs.developers.optimizely.com/platform-optimizely/v1.4.0-optimizely-graph/docs/fields-selection

Or read my blog: https://world.optimizely.com/blogs/manh-nguyen/dates/2024/4/optimizely-graph-client-dealing-with-cms-data-models-for-query-builder

#332906
Edited, Nov 14, 2024 3:17
* 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.