-
-
Save vtml/195cba6861dfaf06b808965ff1a615ab to your computer and use it in GitHub Desktop.
Extended Sitecore SearchQuery to support sorting and more complex search criteria
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using GraphQL.Types; | |
using Sitecore.ContentSearch; | |
using Sitecore.ContentSearch.Linq; | |
using Sitecore.ContentSearch.Linq.Utilities; | |
using Sitecore.ContentSearch.Utilities; | |
using Sitecore.Data; | |
using Sitecore.Data.Managers; | |
using Sitecore.Globalization; | |
using Sitecore.Services.GraphQL.Content.GraphTypes.ContentSearch; | |
using Sitecore.Services.GraphQL.GraphTypes.Connections; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace Website.SitecoreExtensions.GraphQL | |
{ | |
public class ExtendedSearchQuery : Sitecore.Services.GraphQL.Content.Queries.SearchQuery | |
{ | |
public ExtendedSearchQuery() | |
{ | |
this.Arguments.Add(new QueryArgument<StringGraphType>() | |
{ | |
Name = "sortBy", | |
Description = "Sort by a field" | |
}); | |
this.Arguments.Add(new QueryArgument<BooleanGraphType>() | |
{ | |
Name = "sortDesc", | |
Description = "Specify Desc vs ascending", | |
DefaultValue = false | |
}); | |
} | |
protected override ContentSearchResults Resolve(ResolveFieldContext context) | |
{ | |
var inputPathOrIdOrShortId = context.GetArgument<string>("rootItem"); | |
ID rootId = null; | |
if (!string.IsNullOrWhiteSpace(inputPathOrIdOrShortId) && Sitecore.Services.GraphQL.Content.GraphTypes.IdHelper.TryResolveItem(this.Database, inputPathOrIdOrShortId, out var result1)) | |
{ | |
rootId = result1.ID; | |
} | |
if (!Language.TryParse(context.GetArgument<string>("language") ?? Sitecore.Context.Language.Name ?? LanguageManager.DefaultLanguage.Name, out var result2)) | |
{ | |
result2 = null; | |
} | |
var keywordArg = context.GetArgument<string>("keyword"); | |
var nullable1 = context.GetArgument("version", new bool?()); | |
var flag = !nullable1.HasValue || nullable1.GetValueOrDefault(); | |
var indexName = context.GetArgument<string>("index"); | |
var sortBy = context.GetArgument<string>("sortBy"); | |
var dateFrom = context.GetArgument<string>("dateFrom"); | |
var dateTo = context.GetArgument<string>("dateTo"); | |
bool? sortDesc = context.GetArgument<bool>("sortDesc"); | |
var fieldEquals = context.GetArgument("fieldsEqual", new object[0]).OfType<Dictionary<string, object>>(); | |
var facets = (IEnumerable<string>)(context.GetArgument<IEnumerable<string>>("facetOn") ?? new string[0]); | |
SitecoreIndexableItem rootItem = null; | |
if (rootId != (ID)null) | |
{ | |
rootItem = Sitecore.Context.Database.GetItem(rootId); | |
} | |
if (rootItem == null) | |
{ | |
rootItem = Sitecore.Context.Database.GetRootItem(); | |
} | |
// user can force the index by passing in an index name | |
// if they don't force an index, try to get determine the index from the rootitem | |
// if there is no root item, then just use the default Sitecore indexes and pray | |
var index = !string.IsNullOrWhiteSpace(indexName) | |
? ContentSearchManager.GetIndex(indexName) | |
: rootItem != null | |
? ContentSearchManager.GetIndex(rootItem) | |
: ContentSearchManager.GetIndex($"sitecore_{this.Database.Name.ToLower()}_index"); | |
using (var searchContext = index.CreateSearchContext()) | |
{ | |
var queryable = searchContext.GetQueryable<ContentSearchResult>(); | |
if (rootId != (ID)null) | |
queryable = queryable.Where(result => result.AncestorIDs.Contains(rootId)); | |
if (!string.IsNullOrWhiteSpace(keywordArg)) | |
queryable = queryable.Where(result => result.Content.Contains(keywordArg)); | |
if (result2 != null) | |
{ | |
var resultLanguage = result2.Name; | |
queryable = queryable.Where(result => result.Language == resultLanguage); | |
} | |
if (flag) | |
queryable = queryable.Where(result => result.IsLatestVersion); | |
foreach (var dictionary in fieldEquals) | |
{ | |
var name = dictionary["name"].ToString(); | |
var value = dictionary["value"].ToString(); | |
if (value.Contains("notin:")) | |
{ | |
var parts = value.Split(':'); | |
var values = parts[1].Split(','); | |
var predicateBuilder = PredicateBuilder.True<ContentSearchResult>(); | |
values.ForEach( | |
v => predicateBuilder = predicateBuilder.And(result => !result[name].Equals(v))); | |
queryable = queryable.Where(predicateBuilder); | |
} | |
else if (value.Contains("in:")) | |
{ | |
var parts = value.Split(':'); | |
var values = parts[1].Split(','); | |
var predicateBuilder = PredicateBuilder.False<ContentSearchResult>(); | |
values.ForEach( | |
v => predicateBuilder = predicateBuilder.Or(result => result[name].Equals(v))); | |
queryable = queryable.Where(predicateBuilder); | |
} | |
else if (value.Contains("or:")) | |
{ | |
var parts = value.Split(':'); | |
var predicateBuilder = PredicateBuilder.False<ContentSearchResult>(); | |
predicateBuilder.Or(result => result[name].Equals(parts[1])); | |
queryable = queryable.Where(predicateBuilder); | |
} | |
else | |
{ | |
queryable = queryable.Where(result => result[name].Equals(value)); | |
} | |
} | |
foreach (var str in facets) | |
{ | |
var facet = str; | |
queryable = queryable.FacetOn(result => result[facet]); | |
} | |
var nullable2 = context.GetArgument("after", new int?()); | |
if (!string.IsNullOrEmpty(sortBy)) | |
{ | |
if (sortDesc.HasValue && sortDesc == true) | |
{ | |
queryable = queryable.OrderByDescending(result => result[sortBy]); | |
} | |
else | |
{ | |
queryable = queryable.OrderBy(result => result[sortBy]); | |
} | |
} | |
var results = new ContentSearchResults( | |
queryable.ApplyEnumerableConnectionArguments<ContentSearchResult, object>(context).GetResults(), | |
nullable2 ?? 0); | |
return results; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment