【问题标题】:How to Implement JSON Facet API in SolrNet如何在 SolrNet 中实现 JSON Facet API
【发布时间】:2018-04-22 12:01:46
【问题描述】:

我想在 Solr 中创建聚合函数我从 Post 找到了方法 但是我无法在 SolrNet 中实现它

如何在SolrNet中实现JSON Facet API

        ISolrOperations<DeviceReadings> solr = connection.GetSolrInstance();
        QueryOptions queryOption = new QueryOptions
        {
            Rows = 0,
            FilterQueries = new ISolrQuery[] {
            new SolrQueryByField("playerId", query.PlayerId.ToString()),
            new SolrQueryByRange<DateTime>("dateTime", query.DateTimeFrom, query.DateTimeTo)
            },
            Facet = new FacetParameters
            {
                Queries = new List<ISolrFacetQuery>
                {
                    new SolrFacetFieldQuery("heartRate")
                }
            }

        };
        queryOption.ExtraParams = new KeyValuePair<string, string>[] {
            new KeyValuePair<string,string>("wt", "xml")
        };
        //Execute the query
        solrResults = solr.Query(SolrQuery.All, queryOption);

更新 我是使用 ExtraParams 完成的

  queryOption.ExtraParams = new KeyValuePair<string, string>[] {
            new KeyValuePair<string,string>("wt", "xml"),
            new KeyValuePair<string,string>("json.facet", "{heartRateMin: 'min(heartRate)',heartRateMax: 'max(heartRate)',heartRateAvg: 'avg(heartRate)',distance: 'sum(distance)',calories: 'sum(calories)'}")
        };

solrResults = await solr.QueryAsync(SolrQuery.All, queryOption);

 ReadingsResponseExtraction extractResponse = new ReadingsResponseExtraction();
 extractResponse.SetHeader(queryResponce, solrResults);
 extractResponse.SetBody(queryResponce, solrResults);
 extractResponse.SetFacets(queryResponce, solrResults);

 //Return response;
 return queryResponce;

ReadingsResponseExtraction.cs

internal class ReadingsResponseExtraction
{
    //Extract parts of the SolrNet response and set them in QueryResponse class
    internal void SetHeader(DeviceQueryResponse queryResponce, SolrQueryResults<DeviceReadings> solrResults)
    {
        queryResponce.QueryTime = solrResults.Header.QTime;
        queryResponce.Status = solrResults.Header.Status;
        queryResponce.TotalHits = solrResults.NumFound;
    }

    internal void SetBody(DeviceQueryResponse queryResponce, SolrQueryResults<DeviceReadings> solrResults)
    {
        queryResponce.Result = (List<DeviceReadings>)solrResults;
    }

    internal void SetFacets(DeviceQueryResponse queryResponse, SolrQueryResults<DeviceReadings> solrResults)
    {
        queryResponse.HeartRateMin = (int)solrResults.Stats["heartRate"].Min;
        queryResponse.HeartRateMax = (int)solrResults.Stats["heartRate"].Max;
        queryResponse.HeartRateAvg = (int)solrResults.Stats["heartRate"].Mean;

        queryResponse.Distance = solrResults.Stats["distance"].Sum;
        queryResponse.Calories = solrResults.Stats["calories"].Sum;
    }
}

如何从 extraParames 中获取这些值

【问题讨论】:

    标签: c# asp.net solr solrnet


    【解决方案1】:

    据我所知,SolrNet 还没有支持 json.facet 的 .NET API。但是,您始终可以通过 QueryOptions.ExtraParams 属性附加额外的查询参数。根据您的示例:

    queryOption.ExtraParams = new KeyValuePair<string, string>[] {
        new KeyValuePair<string,string>("wt", "xml"),
        new KeyValuePair<string,string("json.facet", "YOUR_JSON_FACET"),
    };
    

    YOUR_JSON_FACET 可以只是一个 JSON 字符串文字,也可以是一个序列化为 JSON 的对象。例如

    var jsonFacet = new
    {
        heartRate = new {
            type= "terms",
            field= "heartRate",
        }
    };
    
    JsonConvert.SerializeObject(jsonFacet, Formatting.None);
    

    接下来,您需要从 Solr 的响应中读取分面值。可能有更简洁的方法可以做到这一点,但不涉及更改 SolrNet 内部结构的一种方法是编写您自己的 Query 方法,该方法也输出原始 XML。从该原始 XML 中,您可以读取适当的 json.facet 节点。

    public static SolrQueryResults<T> QueryWithRawXml<T>(this ISolrOperations<T> operations, 
            ISolrQuery query, QueryOptions queryOptions, out XDocument xml)
        {
            var executor = (SolrQueryExecuter<T>)ServiceLocator.Current.GetInstance<ISolrQueryExecuter<T>>();
    
            var connectionKey = string.Format("{0}.{1}.{2}", typeof(SolrConnection), typeof(T), typeof(SolrConnection));
            var connection = ServiceLocator.Current.GetInstance<ISolrConnection>(connectionKey);
            var parser = ServiceLocator.Current.GetInstance<ISolrAbstractResponseParser<T>>();
    
            var parameters = executor.GetAllParameters(query, queryOptions);
            var responseXml = connection.Get(executor.Handler, parameters);
    
            xml = XDocument.Parse(responseXml);
    
            var results = new SolrQueryResults<T>();
            parser.Parse(xml, results);
    
            return results;
        }
    
    public IEnumerable<KeyValuePair<string, int> GetJsonFacets(
        XDocument xml, string facetFieldName, string countFieldName = "count")
    {
        var response = xml.Element("response");
    
        if (response == null)
        {
            yield break;
        }
    
        var mainFacetNode = response
            .Elements("lst")
            .FirstOrDefault(e => e.Attribute("name")?.Value == "facets");
    
        if (mainFacetNode == null)
        {
            yield break;
        }
    
        var groupFacetElement = mainFacetNode
            .Elements("lst")
            .FirstOrDefault(x => x.Attribute("name")?.Value == facetFieldName);
    
        if (groupFacetElement == null)
        {
            yield break;
        }
    
        var buckets = groupFacetElement.Elements("arr")
            .FirstOrDefault(x => x.Attribute("name")?.Value == "buckets");
    
        if (buckets == null)
        {
            yield break;
        }
    
        foreach (var bucket in buckets.Elements("lst"))
        {
            var valNode = bucket.Elements()
                .FirstOrDefault(x => x.Attribute("name")?.Value == "val");
            var countNode = bucket.Elements()
                .FirstOrDefault(x => x.Attribute("name")?.Value == countFieldName);
    
            int count;
            if (valNode != null && countNode != null && 
                int.TryParse(countNode.Value, out count))
            {
                yield return new KeyValuePair<string, int>(valNode.Value,count)
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-24
      • 1970-01-01
      • 2013-10-04
      • 1970-01-01
      • 2013-02-18
      相关资源
      最近更新 更多