如何让SolrNet中的建议器组件工作?

时间:2013-01-07 11:16:30

标签: c# .net solr solrnet

我已经配置了solrconfig.xml和schema.xml来查询建议。

我可以从网址

获取建议
http://localhost:8080/solr/collection1/suggest?q=ha&wt=xml

我的SolrConfig.xml看起来像

当然,我的solr查询看起来像

<fields>
    <!-- declare fields of entity class -->
    <!-- type will specify the table name -->
    <field name="type" type="string" indexed="true" stored="true"  />

    <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
    <field name="name" type="text_general" indexed="true" stored="true" omitNorms="true"/>

    <field name="text" type="text_general" indexed="true" stored="false" multiValued="true"/>
    <field name="_version_" type="long" indexed="true" stored="true"/>

    <!-- unique field -->
    <field name="uid" type="uuid" indexed="true" stored="true" />

  </fields>

  <uniqueKey>uid</uniqueKey>

  <copyField source="name" dest="text"/>

  <types>
    <fieldType name="uuid" class="solr.UUIDField" indexed="true" />
    <fieldType name="string" class="solr.StrField" sortMissingLast="true" />
    <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>

    <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>
    .....
    </types>

我的schema.xml看起来像这样

<searchComponent name="suggest" class="solr.SpellCheckComponent">
    <!-- a spellchecker built from a field of the main index -->
    <lst name="spellchecker">
      <str name="name">suggest</str>
      <str name="field">name</str>
      <str name="classname">org.apache.solr.spelling.suggest.Suggester</str>
      <str name="lookupImpl">org.apache.solr.spelling.suggest.tst.TSTLookup</str>
      <str name="buildOnCommit">true</str>          
      <str name="distanceMeasure">internal</str>
      <float name="accuracy">0.5</float>
      <int name="maxEdits">2</int>
      int name="minPrefix">1</int>
      <int name="maxInspections">5</int>
      <int name="minQueryLength">4</int>
      <float name="maxQueryFrequency">0.01</float>
       <float name="thresholdTokenFrequency">.01</float>      
    </lst>

    <!-- a spellchecker that can break or combine words.  See "/spell" handler below for usage -->
    <lst name="spellchecker">
      <str name="name">wordbreak</str>
      <str name="classname">solr.WordBreakSolrSpellChecker</str>
      <str name="field">name</str>
      <str name="combineWords">true</str>
      <str name="breakWords">true</str>
      <int name="maxChanges">10</int>
    </lst>
</searchComponent>

<requestHandler name="/suggest" class="solr.SearchHandler" startup="lazy">
    <lst name="defaults">
      <str name="df">text</str>
      <!-- Solr will use suggestions from both the 'default' spellchecker
           and from the 'wordbreak' spellchecker and combine them.
           collations (re-written queries) can include a combination of
           corrections from both spellcheckers -->
      <str name="spellcheck">true</str>
      <str name="spellcheck.dictionary">suggest</str>
      <!--<str name="spellcheck.dictionary">wordbreak</str>-->
      <str name="spellcheck">on</str>
      <str name="spellcheck.extendedResults">true</str>       
      <str name="spellcheck.count">10</str>
      <str name="spellcheck.alternativeTermCount">5</str>
      <str name="spellcheck.maxResultsForSuggest">5</str>       
      <str name="spellcheck.collate">true</str>
      <str name="spellcheck.collateExtendedResults">true</str>  
      <str name="spellcheck.maxCollationTries">10</str>
      <str name="spellcheck.maxCollations">5</str>         
    </lst>
    <arr name="last-components">
      <str>spellcheck</str>
    </arr>
  </requestHandler>

我调用SolrNet API的代码如下所示

new SolrBaseRepository.Instance<T>().Start();
        var solr = ServiceLocator.Current.GetInstance<ISolrOperations<T>>();
        var options = new QueryOptions
        {
            FilterQueries = new ISolrQuery[] { new SolrQueryByField("type", type) }
        };
        var results = solr.Query(keyword, options);
        return results;

但是,我没有得到任何数据。 结果计数为零。而且结果中的拼写检查也是零。

我也没有在结果中看到建议清单。

enter image description here

请帮忙

5 个答案:

答案 0 :(得分:5)

我有完全相同的要求,但找不到任何方法可以轻松处理SolrNet的Suggester结果。不幸的是,SolrNet似乎是围绕默认的/select请求处理程序构建的,目前不支持包括/suggest在内的任何其他处理程序用于对象类型映射(T)。它希望所有映射都与索引的Solr文档结果一起发生,而不是建议结果。

因此,@Paige Cook's answer对我不起作用。带映射的T类型与建议者结果响应不兼容。从初始化请求(Startup.Init<T>())到查询(ISolrQueryResults<T> results = solr.Query())的所有标准管道代码都需要映射的Solr文档类型,而不是建议者提供的简单字符串数组。

因此,(类似于@dfay)我发出了一个Web请求,并从XML Web响应中解析出建议的结果。 SolrConnection类用于此:

string searchTerm = "ha";
string solrUrl = "http://localhost:8080/solr/collection1";
string relativeUrl = "/suggest";
var parameters = new Dictionary<string, string>
                {
                    {"q", searchTerm},
                    {"wt", "xml"},
                };

var solrConnection = new SolrConnection(solrUrl);
string response = solrConnection.Get(relativeUrl, parameters);
// then use your favorite XML parser to extract 
// suggestions from the reponse string

或者,请求可以使用wt=json参数返回JSON响应,而不是XML:

var parameters = new Dictionary<string, string>
                {
                    {"q", searchTerm},
                    {"wt", "json"}, // change this!
                };
// then use your favorite JSON parser

答案 1 :(得分:2)

为了针对您设置的/suggest请求处理程序执行查询,您需要使用SolrNet QueryOptions中的ExtraParameters设置qt Solr参数,如下所示:

 new SolrBaseRepository.Instance<T>().Start();
 var solr = ServiceLocator.Current.GetInstance<ISolrOperations<T>>();
 var options = new QueryOptions
 {
     FilterQueries = new ISolrQuery[] { new SolrQueryByField("type", type) },
     ExtraParams = new Dictionary<string, string>{{"qt", "suggest"}},
 };
 var results = solr.Query(keyword, options);
 return results;

否则,您的查询仍然针对标准/select请求处理程序(或您在solrconfig.xml中定义为默认值的任何内容)执行。

答案 2 :(得分:1)

请参阅http://wiki.apache.org/solr/SolrRequestHandler,特别是有关旧handleSelect = true行为的部分。如果您针对较新的Solr服务器运行,这很可能是您的问题。 (即设置“qt”无效,并且必须更改SolrNet中的默认处理程序或Solr配置需要设置handleSelect = true。)以下是我在以下情况中解决此问题的方法:

ISolrConnection connection = ServiceLocator.Current.GetInstance<ISolrConnection>();
List<KeyValuePair<string, string>> termsParams = new List<KeyValuePair<string, string>>();
termsParams.Add(new KeyValuePair<string, string>("terms.fl", "name"));
termsParams.Add(new KeyValuePair<string, string>("terms.prefix", mySearchString));
termsParams.Add(new KeyValuePair<string, string>("terms.sort", "count"));
string xml = connection.Get("/terms", termsParams);

ISolrAbstractResponseParser<Document> parser = ServiceLocator.Current.GetInstance<ISolrAbstractResponseParser<Document>>();
SolrQueryResults<Document> results = new SolrQueryResults<Document>();
parser.Parse(System.Xml.Linq.XDocument.Parse(xml), results);

TermsResults termResults = results.Terms;
foreach (TermsResult result in termResults)
{
    foreach (KeyValuePair<string, int> kvp in result.Terms)
    {
        //... do something with keys
    }
}

基本上我使用SolrNet解析器和连接代码,但不使用查询内容。希望这会有所帮助。

答案 3 :(得分:0)

传递qt参数不起作用,至少在Solr 4.7中不行,即使SolrConfig中的handleSelect = true也是如此。您可以通过指定与默认/ select非常不同的自定义处理程序进行验证,例如,让您使用edismax并在ExtraParams中发送debugQuery = true并在Fiddler中捕获结果。

另外,如果您阅读handleSelect标志的说明,它会说&#34;如果请求使用&#34; / select&#34;但是没有该名称的请求处理程序&#34;。

您不想触摸或禁用/ select处理程序,因为Solr自己使用它。

我最终使用ExtraParams传递我在自定义处理程序中定义的所有值,但没有那么多。看起来不仅仅是使用SolrNET的一部分然后进行结果解析。

答案 4 :(得分:0)

使用新版本的SolrNet(至少.net 4.6),您可以更改默认处理程序“ / select”。 尝试使用这种方式致电您的建议处理程序。

using CommonServiceLocator;
using SolrNet;
using SolrNet.Commands.Parameters;

Startup.Init<MwDoc>("http://localhost:8983/solr/mycore");
var solr = ServiceLocator.Current.GetInstance<ISolrOperations<MyClass>>();

QueryOptions options = new QueryOptions()
            {
                RequestHandler = new RequestHandlerParameters("/suggest"),
                // define your other Options here
            };
solr.Query("keyword to search", options);