After manually implementing support for the Edm.GeographyPoint
field type (per Is it possible to get Azure Search to support EDM.GeographyPoint?), I was happy to notice an answer on a related question from Dawid Rutkowski (Using Sitecore SXA Location Search with Azure Search) indicating that the SXA team has implemented this same functionality.
I've converted my custom index configurations over to use the relevant SXA types (e.g. Sitecore.XA.Foundation.Search.Providers.Azure.CloudSearchProviderIndex
). I'm able to rebuild my index in Sitecore and see good values in the Azure index, for example:
...
"geo_coordinate": {
"type": "Point",
"coordinates": [
-90.169,
33.4945
],
"crs": {
"type": "name",
"properties":
{
"name": "EPSG:4326"
}
}
}
...
Now, I'm trying to query the index using the Sitecore search API and am getting the following run-time error:
Constructor on type 'Sitecore.XA.Foundation.Search.Providers.Azure.LinqToCloudIndex`1[[Acme.Foundation.Search.Models.FooResult, Acme.Foundation.Search, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' not found.
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Activator.CreateInstance(Type type, Object[] args)
at Sitecore.XA.Foundation.Search.Providers.Azure.CloudSearchProviderIndex.<>c.<InitializeServiceCollectionClient>b__2_0(ServiceBuilder builder)
at Sitecore.ContentSearch.Azure.ServiceCollection.GetInstance(Type concreteType, Object[] args)
at Sitecore.ContentSearch.Azure.ServiceCollection.GetInstance[T](Object[] args)
at Sitecore.ContentSearch.Azure.CloudSearchSearchContext.GetQueryable[TItem](IExecutionContext[] executionContexts)
at Acme.Foundation.Search.Repositories.FooRepository.GetFoos(...)
...
Here are my index configurations:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:search="http://www.sitecore.net/xmlconfig/search/">
<sitecore search:require="azure">
<contentSearch>
<indexConfigurations>
<defaultAzureFoosIndexConfiguration ref="contentSearch/indexConfigurations/defaultCloudIndexConfiguration">
<fieldMap ref="contentSearch/indexConfigurations/defaultCloudIndexConfiguration/fieldMap">
<fieldNames hint="raw:AddFieldByFieldName">
<field fieldName="geo_coordinate" boost="1f" facetable="NO" type="Sitecore.XA.Foundation.Search.Providers.Azure.Geospatial.GeoPoint" settingType="Sitecore.ContentSearch.Azure.CloudSearchFieldConfiguration, Sitecore.ContentSearch.Azure" />
</fieldNames>
</fieldMap>
<documentOptions ref="contentSearch/indexConfigurations/defaultCloudIndexConfiguration/documentOptions">
<fields hint="raw:AddComputedIndexField">
<field fieldName="geo_coordinate">Acme.Foundation.Search.ComputedFields.CoordinateComputedIndexField, Acme.Foundation.Search</field>
</fields>
</documentOptions>
</defaultAzureFoosIndexConfiguration>
</indexConfigurations>
</contentSearch>
</sitecore>
</configuration>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:search="http://www.sitecore.net/xmlconfig/search/" xmlns:tenant="http://www.sitecore.net/xmlconfig/tenant/">
<sitecore role:require="Standalone or ContentManagement or ContentDelivery" search:require="azure">
<contentSearch>
<configuration type="Sitecore.ContentSearch.ContentSearchConfiguration, Sitecore.ContentSearch">
<indexes hint="list:AddIndex">
<index id="foo_web_index" type="Sitecore.XA.Foundation.Search.Providers.Azure.CloudSearchProviderIndex, Sitecore.XA.Foundation.Search.Providers.Azure">
<param desc="name">$(id)</param>
<param desc="connectionStringName">cloud.search</param>
<param desc="totalParallelServices">5</param>
<param desc="propertyStore" ref="contentSearch/indexConfigurations/databasePropertyStore" param1="$(id)" />
<configuration ref="contentSearch/indexConfigurations/defaultAzureFoosIndexConfiguration" />
<strategies hint="list:AddStrategy">
<strategy ref="contentSearch/indexConfigurations/indexUpdateStrategies/onPublishEndAsync" />
</strategies>
<commitPolicyExecutor type="Sitecore.ContentSearch.CommitPolicyExecutor, Sitecore.ContentSearch">
<policies hint="list:AddCommitPolicy">
<policy type="Sitecore.ContentSearch.TimeIntervalCommitPolicy, Sitecore.ContentSearch" />
<policy type="Sitecore.ContentSearch.ModificationCountCommitPolicy, Sitecore.ContentSearch">
<Limit>1000</Limit>
</policy>
</policies>
</commitPolicyExecutor>
<locations hint="list:AddCrawler">
<crawler type="Sitecore.ContentSearch.SitecoreItemCrawler, Sitecore.ContentSearch">
<Database>web</Database>
<Root>/sitecore/content/Tenant/Global/Foos/</Root>
</crawler>
</locations>
<enableItemLanguageFallback>false</enableItemLanguageFallback>
<enableFieldLanguageFallback>false</enableFieldLanguageFallback>
</index>
</indexes>
</configuration>
</contentSearch>
</sitecore>
</configuration>
I'm creating the search context as per usual:
var ctx = ContentSearchManager.GetIndex("foo_web_index").CreateSearchContext();
...and am querying the index like so:
var results = ctx.GetQueryable<FooResult>().Where(...)...;
The run-time error is thrown on this line (on GetQueryable<T>()
).
What I have verified/tried thus far:
- My custom index configs are patched after
Sitecore.XA.Foundation.Search.Azure.config
(...\App_Config\Modules\SXA\Z.Foundation.Overrides\Sitecore.XA.Foundation.Search.Azure.config
) and should therefore pick up all the SXA goodness. - There aren't ostensibly any
<param />
elements I'm missing. - The run-time type of the search context is
Sitecore.XA.Foundation.Search.Providers.Azure.CloudSearchSearchContext
, as expected. - Inheriting from
SearchResultItem
onFooResult
doesn't change the error. - Adding a parameterless constructor on
FooResult
doesn't change the error. - Referencing an OOTB SXA index rather than the custom index (e.g.
sitecore_sxa_web_index
) yields the same error; it doesn't seem to be unique to the index.
Reflecting Sitecore.XA.Foundation.Search.Providers.Azure.dll
, I think this is the method interest:
protected virtual ServiceCollectionClient InitializeServiceCollectionClient()
{
ServiceCollectionClient collectionClient = new ServiceCollectionClient();
collectionClient.Register(typeof (LinqToCloudIndex<>), (Func<ServiceBuilder, object>) (builder => ServiceBuilder.CreateInstanceOfType(typeof (LinqToCloudIndex<>), builder.Types.ToArray<Type>(), (object) builder.Arguments)));
collectionClient.Register(typeof (AbstractSearchIndex), (Func<ServiceBuilder, object>) (builder => (object) this));
collectionClient.Register(typeof (QueryStringBuilder), (Func<ServiceBuilder, object>) (builder => (object) new QueryStringBuilder(new FilterQueryBuilder(), new SearchQueryBuilder(), true)));
return collectionClient;
}
Specifically this line:
collectionClient.Register(typeof (LinqToCloudIndex<>), (Func<ServiceBuilder, object>) (builder => ServiceBuilder.CreateInstanceOfType(typeof (LinqToCloudIndex<>), builder.Types.ToArray<Type>(), (object) builder.Arguments)));
As this is reflected code, the empty <>
probably indicates a cast but, I got nothing 😊.
What am I missing?
- Something in the configs?
- Some fancy thing with DI?
- A specific way to instantiate the search context?
Version notes:
Sitecore XP 9.1.1 rev. 002459
Sitecore Experience Accelerator 1.8.1 rev. 190319
FooResult
using thesitecore_web_index
to rule out the index itself being the issue?LinqToCloudIndex
orCloudSearchProviderIndex
. Those need to be used in order to have properly working features like ordering by distance or searching within a radius. Few questions... What version of SXA do you have? Why you have customgeo_coordinate
fields instead of SXA ones? Why are you using custom computed field typeAcme.Foundation.Search.ComputedFields.CoordinateComputedIndexField
instead of SXA one?Sitecore XP 9.1.1 rev. 002459
withSitecore Experience Accelerator 1.8.1 rev. 190319
. I have a custom template that also has acoordinate
field; I wanted to use a customgeo_coordinate
field just to keep things separate and avoid collision/confusion. The custom computed field exists for the same reason and is keyed to my owncoordinate
field."sitecore_sxa_web_index"
(meaningContentSearchManager.GetIndex("sitecore_sxa_web_index").CreateSearchContext()
)...yields the same error. So it doesn't appear to be unique to the custom index.