проблема с solrnet при подкачке ядер

Я использую SolrNet.0.3.1 и SolrNet.Ninject.0.3.1 в приложении ASP.NET MVC 3, указывающем на экземпляр Solr 3.4.

Я использую несколько ядер, поэтому я могу проверить изменения схемы на втором ядре, не нарушая работу приложения. Многоядерность сама по себе не является проблемой; приложение с радостью использует «core-live», в то время как я избиваю «core-ondeck» до смерти глупыми опечатками и настройками схемы.

Служба Solrnet расположена по адресу http://[server]:8983/[solr-instance]/, и по умолчанию используется core-live через настройку defaultCoreName экземпляра solr.xml.

# solrnet service location
http://[server]:8983/[solr-instance]/

# instance's solr.xml settings for multiple cores
<solr sharedLib="lib" persistent="true">
  <cores adminPath="/admin/cores" defaultCoreName="core-live">
    <core name="core-live" instanceDir="conf/core0/" />
    <core name="core-ondeck" instanceDir="conf/core1/" />
  </cores>
</solr>

После тестирования изменений схемы на втором ядре из графического интерфейса администратора браузера Solr, я меняю местами ядра, и теперь приложение должно использовать ядро, которое я только что изменил.

# swap cores so app uses modified schema and index
curl "http://[server]:8983/[solr-instance]/admin/cores?action=SWAP&name=core-live&other=core-ondeck"

За исключением того, что solrnet не обращает внимания на изменения схемы и, например, сбоит при запросе, потому что поле, которое имело тип String в старой схеме, теперь имеет тип DateTime в новой.

[ArgumentException: Object of type 'System.DateTime' cannot be converted to type 'System.String'.]
   System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast) +6429224
   System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr) +12711129
   System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig) +129
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) +522
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +38
   System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index) +44
   SolrNet.Impl.DocumentPropertyVisitors.RegularDocumentVisitor.Visit(Object doc, String fieldName, XmlNode field) in c:\prg\SolrNet\svn\SolrNet\Impl\DocumentPropertyVisitors\RegularDocumentVisitor.cs:48
   SolrNet.Impl.DocumentPropertyVisitors.AggregateDocumentVisitor.Visit(Object doc, String fieldName, XmlNode field) in c:\prg\SolrNet\svn\SolrNet\Impl\DocumentPropertyVisitors\AggregateDocumentVisitor.cs:37
   SolrNet.Impl.DocumentPropertyVisitors.DefaultDocumentVisitor.Visit(Object doc, String fieldName, XmlNode field) in c:\prg\SolrNet\svn\SolrNet\Impl\DocumentPropertyVisitors\DefaultDocumentVisitor.cs:39
   SolrNet.Impl.SolrDocumentResponseParser`1.ParseDocument(XmlNode node, ICollection`1 fields) in c:\prg\SolrNet\svn\SolrNet\Impl\SolrDocumentResponseParser.cs:65
   SolrNet.Impl.SolrDocumentResponseParser`1.ParseResults(XmlNode parentNode) in c:\prg\SolrNet\svn\SolrNet\Impl\SolrDocumentResponseParser.cs:50
   SolrNet.Impl.ResponseParsers.ResultsResponseParser`1.Parse(XmlDocument xml, SolrQueryResults`1 results) in c:\prg\SolrNet\svn\SolrNet\Impl\ResponseParsers\ResultsResponseParser.cs:41
   SolrNet.Impl.SolrQueryResultParser`1.Parse(String r) in c:\prg\SolrNet\svn\SolrNet\Impl\SolrQueryResultParser.cs:46
   SolrNet.Impl.SolrQueryExecuter`1.Execute(ISolrQuery q, QueryOptions options) in c:\prg\SolrNet\svn\SolrNet\Impl\SolrQueryExecuter.cs:309
   SolrNet.Impl.SolrBasicServer`1.Query(ISolrQuery query, QueryOptions options) in c:\prg\SolrNet\svn\SolrNet\Impl\SolrBasicServer.cs:83
   SolrNet.Impl.SolrServer`1.Query(ISolrQuery query, QueryOptions options) in c:\prg\SolrNet\svn\SolrNet\Impl\SolrServer.cs:50
   Andornot.FhaPhem.Core.Search.SolrSearchOperations.GetResults(ISearchParameters searchParameters) in C:\svn\Client Projects\Fraser Health\PHEM\trunk\Web\Andornot.FhaPhem.Core\Search\SolrSearchOperations.cs:55
   Andornot.FhaPhem.Core.Search.SolrSearchOperations.Query(ISearchParameters searchParameters) in C:\svn\Client Projects\Fraser Health\PHEM\trunk\Web\Andornot.FhaPhem.Core\Search\SolrSearchOperations.cs:29
   Andornot.FhaPhem.Web.Controllers.SearchController.Results(Nullable`1 id) in C:\svn\Client Projects\Fraser Health\PHEM\trunk\Web\Andornot.FhaPhem.Web\Controllers\SearchController.cs:77
   lambda_method(Closure , ControllerBase , Object[] ) +118
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +264
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39
   System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +129
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +826410
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +826410
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +314
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +825632
   System.Web.Mvc.Controller.ExecuteCore() +159
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +335
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +62
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +20
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +54
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +469
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +375

Как обновить понимание схемы solrnet на лету таким образом, чтобы это работало с заменой ядер?


person Peaeater    schedule 30.11.2011    source источник


Ответы (2)


Вот аналогичная ситуация с использованием инструментов, которые, вероятно, более знакомы:

У вас есть реляционная база данных (скажем, Microsoft SQL Server) с таблицей «Person» с полем «data» типа varchar. В вашем коде вы получаете доступ к этой таблице через ORM (NHibernate или EF, не имеет значения), где у вас есть класс Person со свойством data типа string в C#.

Теперь вы редактируете схему таблицы с помощью SQL Server Enterprise Manager и меняете тип данных поля «данные» на дату и время.

Если вы не обновите свой код, чтобы отразить это изменение схемы, ваш код сломается.

Это именно то, что происходит в вашем случае, за исключением того, что Solr вместо реляционной базы данных и SolrNet вместо ORM. Вы пытаетесь получить дату из Solr в строковое свойство.

Решения:

  • Обновите свой код, чтобы отразить изменения в вашей новой схеме.
  • Переключитесь на полностью свободное сопоставление SolrNet. На самом деле не рекомендуется, он, вероятно, все равно взорвется с таким изменением.
person Mauricio Scheffer    schedule 30.11.2011
comment
Спасибо и вам, и @PaigeCook! Я предположил (без всякой причины), что solrnet будет обрабатывать значение поля в соответствии с типом свойства карты поля, который я установил в своей карте, независимо от типа поля, установленного в схеме, но solrnet на самом деле анализирует значения поля ответа настолько разумно, насколько это возможно? Он делает это не из своего знания схемы, не так ли? Потому что я мог создать там любой сумасшедший тип поля. Зачем анализировать поля ответа независимо от какой-либо ссылки на мою карту полей? Просто любопытно. - person Peaeater; 01.12.2011
comment
@Peaeater: извините, я не очень понимаю вопрос ... DateTime - это DateTime, а строка - это строка ... как бы вы решили аналогичную проблему SQL / ORM? - person Mauricio Scheffer; 02.12.2011
comment
По аналогии с SQL/ORM тип данных, отображаемый ORM, зависит от ограниченного числа известных типов данных SQL. Но когда solrnet определяет тип .NET из поля схемы solr, он должен сделать менее обоснованное предположение о том, что это за тип данных, не так ли? Думая об этом, я сделал ошибочное предположение, что составленная мной карта поля может управлять картографом. Вместо этого я теперь понимаю, что solrnet больше похож на стандартную ORM, и моя карта полей не влияет на его поведение при интерпретации. - person Peaeater; 06.12.2011
comment
@Peaeater: SolrNet считывает тип данных Solr непосредственно из ответа, а не из схемы (я знаю, что в данном случае это не имеет никакого значения). Solr имеет несколько четко определенных типов полей, которые он использует в своем выводе, т. е. он не является нетипизированным: bool, str, int, float, double, long, arr, date. Сказав это, вы всегда можете переопределить парсеры полей в SolrNet и заставить их вести себя так, как вы хотите. - person Mauricio Scheffer; 06.12.2011

Я полагаю, что ваша проблема связана с тем, как вы настроили сопоставление в SolrNet. Если вы меняете тип поля в своей схеме Solr, вам нужно будет внести такое же соответствующее изменение в сопоставление SolrNet.

Чтобы позволить SolrNet работать с изменениями схемы «на лету», вам необходимо реализовать одно из следующих действий:

  1. Следуйте указаниям раздела "Полностью свободное сопоставление" в документации по сопоставлению SolrNet.
  2. Динамически меняйте сопоставленный класс SolrNet, когда схема была изменена на новый сопоставленный класс, соответствующий новой схеме.

Первый вариант, пожалуй, будет самым простым.

person Paige Cook    schedule 30.11.2011
comment
Я думаю, что с этого момента я просто оставлю вам все вопросы SolrNet по stackoverflow :) - person Mauricio Scheffer; 30.11.2011