Skip to content
This repository was archived by the owner on Aug 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 23 additions & 11 deletions APIs/src/EpiServer.ContentGraph/Api/Querying/GraphQueryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,13 @@
using Microsoft.Extensions.Options;
using System.Text.RegularExpressions;
using EPiServer.ServiceLocation;
using System.Net.Http;
using System;
using System.Threading.Tasks;
using System.Linq;
using System.IO;
using System.Collections.Generic;
using EPiServer.ContentGraph.Helpers.Text;
using EPiServer.ContentGraph.Helpers;
using EPiServer.ContentGraph.Tracing;

namespace EPiServer.ContentGraph.Api.Querying
{
public class GraphQueryBuilder : IQuery
public class GraphQueryBuilder : IQuery, ITraceable
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly HttpClient _httpClient;
Expand All @@ -29,6 +25,10 @@ public class GraphQueryBuilder : IQuery
private const string UnCachedPath = "?cache=false";
private Dictionary<string, IFragmentBuilder> _fragmentBuilders;
private readonly List<string> typeQueries = new List<string>();
public Action<OptiGraphOptions> GraphOptionsAction;

Guid ITraceable.TraceId => Guid.NewGuid();

public GraphQueryBuilder()
{
_optiGraphOptions = new OptiGraphOptions();
Expand Down Expand Up @@ -119,6 +119,7 @@ public GraphQueryBuilder OperationName(string op)
}
private string GetServiceUrl()
{
UpdateQueryPath();
return _optiGraphOptions.GatewayAddress + _optiGraphOptions.QueryPath;
}
private string GetAuthorization(string body)
Expand Down Expand Up @@ -314,13 +315,24 @@ private void AdditionalInformation(JsonRequest request, string body)
{
request.AddRequestHeader("cg-include-deleted", "true");
}
if (!_optiGraphOptions.Cache)
}
private void UpdateQueryPath()
{
Regex regex = new Regex(@"\?cache=\w*");
if (regex.IsMatch(_optiGraphOptions.QueryPath))
{
_optiGraphOptions.QueryPath =
_optiGraphOptions.QueryPath
.Replace(regex.Match(_optiGraphOptions.QueryPath).Value, $"?cache={_optiGraphOptions.Cache.ToString().ToLower()}");
}
else
{
Regex regex = new Regex(@"\?cache=\w*");
_optiGraphOptions.QueryPath = _optiGraphOptions.QueryPath.Replace(regex.Match(_optiGraphOptions.QueryPath).Value, UnCachedPath);
_optiGraphOptions.QueryPath = $"{_optiGraphOptions.QueryPath}?cache={_optiGraphOptions.Cache.ToString().ToLower()}";
}
if (GraphOptionsAction.IsNotNull()) {
GraphOptionsAction(_optiGraphOptions);
}
}

public void AddQuery(string typeQuery)
{
typeQueries.Add(typeQuery);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using EPiServer.ContentGraph.Api.Querying;
using Azure.Core;
using EPiServer.ContentGraph.Api.Querying;
using EPiServer.ContentGraph.Tracing;

namespace EPiServer.ContentGraph.Extensions
{
Expand All @@ -22,5 +24,26 @@ public static TypeQueryBuilder<T> BeginType<T>(this GraphQueryBuilder queryBuild
{
return queryBuilder.ForType(typeQueryBuilder);
}
/// <summary>
/// Search result has single item will be cached. This will set cache_unique to true and require cache=true in graph client options.
/// </summary>
/// <param name="queryBuilder"></param>
/// <returns></returns>
public static GraphQueryBuilder SingleResultCache(this GraphQueryBuilder queryBuilder)
{
queryBuilder.GraphOptionsAction = options =>
{
if (options.QueryPath.Contains("cache=true"))
{
options.QueryPath += "&cache_uniq=true";
}
else
{
//log warning messge
Trace.Instance.Add(new TraceEvent(queryBuilder, "cache_uniq is set to true but cache is not enable. Please enable it in the config before use."));
}
};
return queryBuilder;
}
}
}
11 changes: 11 additions & 0 deletions APIs/src/EpiServer.ContentGraph/Extensions/TypeSearchExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,16 @@ public static async Task<string> GetRawResultAsync<T>(this TypeQueryBuilder<T> t
return await typeQueryBuilder.ToQuery().BuildQueries().GetRawResultAsync();
}
#endregion

/// <summary>
/// Get single result item then cache this item separately. This will set cache_unique to true and require cache=true in graph client options.
/// </summary>
/// <param name="queryBuilder"></param>
/// <returns></returns>
public static async Task<ContentGraphResult> GetSingleResultCacheAsync<T>(this TypeQueryBuilder<T> typeQueryBuilder)
{
var query = typeQueryBuilder.ToQuery().BuildQueries();
return await query.SingleResultCache().GetResultAsync();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ private static void ConfigureServices(IServiceCollection services)
//o.EnablePreviewFeatures = true;// optional
});

services.AddContentGraphClient();
services.AddContentGraphClient(options=> options.Cache = false);
services.AddContentGraph();
services.AddScoped<IFilterForVisitor, CustomForVisitor>();
services.AddScoped<IFilterForVisitor, FilterPublishedForVisitor>();
Expand Down
Loading