簡體   English   中英

如何在SolrNet中實現JSON Facet API

[英]How to Implement JSON Facet API in SolrNet

我想在Solr中創建聚合函數,我從這篇文章中找到了方法,但是我無法在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獲取這些值

據我所知,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)
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM