solr.net使用实例教程

作者:袖梨 2022-06-25

简介SOLR

Solr是一个高性能,采用Java5开发,Solr基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎,他是基于Lucene的封装比较成熟的全文搜索服务器。solr怎样部署在windows服务器上的,推荐一枚信峰的博客http://www.cnblogs.com/wenxinghaha/tag/.net%20%20solr/,他这里写的比较详细。solr的5.0目前不支持IK分词,所以只好使用4.10版本,solr 的部署也比较方便,再部署的时间可以通过配置文件将数据库的数据索引到solr服务器内,并且能根据索引时间定时的同步数据到solr服务器。

solr在.NET中的驱动

我们在做查询的时间是使用过的C#语言,所以要用到solr在.NET中的驱动,目前比较流行的有solr.NET和easynet.solr,solr.NET是一个比较稳定的开源的solr驱动,easynet.solr是国内一同行在solr.NET上面做了封装,我采用的是最原生的solr.net,驱动下载地址https://github.com/mausch/SolrNet。由于solr服务器是提供restful接口的操作的,所以solrnet对于solr服务的请求其实还是基于http请求的

solrnet的应用

solrnet的应用我就做过多的说明了,在这里我主要是想说一下solrnet的分组查询

附代码

public  class SolrNetOperate
{
    static SolrNetOperate()
    {
        Startup.Init("http://000.000.000.000:8080/solr/logs");
    }
    /// 
    /// 
    /// 查询参数字典
    /// 分页开始标识
    /// 每页数量
    /// 开始时间
    /// 结束时间
    /// 输出参数 总个数
    /// 
    /// oldman 2015年7月23日14:11:43
    public static List GroupingSerach(Dictionary dictPars, int start, int rows,
        DateTime startTime, DateTime endTime, out int count)
    {
        //定义solr
        var solr = ServiceLocator.Current.GetInstance>();
        var queryOptions = new QueryOptions();
        //定义分组
        var groupingParameters = new GroupingParameters();
        groupingParameters.Fields = new Collection { "logs_id" };
        groupingParameters.Ngroups = true; //设置查询分组的总个数为true
        //定义过滤条件
        var timeRange = new SolrQueryByRange("logs_time", startTime, endTime);
        queryOptions.AddFilterQueries(timeRange);
        foreach (string key in dictPars.Keys)
        {
            queryOptions.AddFilterQueries(new SolrQueryByField(key, dictPars[key]));
        }
        //定义排序
        queryOptions.OrderBy = new Collection { new SortOrder("logs_id", Order.DESC) };
        queryOptions.Grouping = groupingParameters;
        queryOptions.Start = start;
        queryOptions.Rows = rows;
        SolrQueryResults res = solr.Query(SolrQuery.All, queryOptions);
        GroupedResults items = res.Grouping["logs_id"];
        count = items.Ngroups ?? 0;
        return items.Groups.Select(item => Convert.ToInt32(item.GroupValue)).ToList();
    }
}


这里是分组后做查询,排序和分页,代码很清晰。




Solrnet教程 


Solrnet基本用法

http://code.google.com/p/solrnet/

 一、开始我们必须生成一个类来映射Solr的Field,下面是Solr默认schema的映射:

public class Product {
    [SolrUniqueKey("id")]
    public string Id { get; set; }
 
    [SolrField("manu_exact")]
    public string Manufacturer { get; set; }
 
    [SolrField("cat")]
    public ICollection Categories { get; set; }
 
    [SolrField("price")]
    public decimal Price { get; set; }
 
    [SolrField("inStock")]
    public bool InStock { get; set; }
}

 

二、初始化:

[TestFixtureSetUp]

public void FixtureSetup() {
    Startup.Init("http://localhost:8983/solr");
}



三、加入document (确保Solr instance正在运行):

[Test]

public void Add() {
    var p = new Product {
        Id = "SP2514N",
        Manufacturer = "Samsung Electronics Co. Ltd.",
        Categories = new[] {
            "electronics",
            "hard drive",
        },
        Price = 92,
        InStock = true,
    };
var solr = ServiceLocator.Current.GetInstance>();
    solr.Add(p).Commit();
}



四、查询document的位置:

[Test]

public void Query() {
    var solr = ServiceLocator.Current.GetInstance>();
    var results = solr.Query(new SolrQueryByField("id", "SP2514N"));
    Assert.AreEqual(1, results.Count);
    Console.WriteLine(results[0].Manufacturer);
}


 

详细教程

一、映射

有三种映射方式:

1.     Attributes (default)

With this method you decorate the properties you want to map with the SolrField and SolrUniqueKey attributes. The attribute parameter indicates the corresponding Solr field name.

Example:

public class Product {
    [SolrUniqueKey("id")]
    public string Id { get; set; }
 
    [SolrField("manu_exact")]
    public string Manufacturer { get; set; }
 
    [SolrField("cat")]
    public ICollection Categories { get; set; }
 
    [SolrField("price")]
    public decimal Price { get; set; }
 
    [SolrField("inStock")]
    public bool InStock { get; set; }
 
    [SolrField("timestamp")]
    public DateTime Timestamp { get; set; }
 
    [SolrField("weight")]
    public double? Weight { get; set;}
}



This way of mapping is implemented by the AttributesMappingManager class.


2.     All-properties

This maps each property of the class to a field of the exact same name as the property (note that Solr field names are case-sensitive). It's implemented by the AllPropertiesMappingManager class. Note that unique keys cannot be inferred, and therefore have to be explicitly mapped. The same mapping as above could be accomplished like this:

public class Product {
    public string id { get; set; }
    public string manu_exact { get; set; }
    public ICollection cat { get; set; }
    public decimal price { get; set; }
    public bool inStock { get; set; }
    public DateTime timestamp { get; set; }
    public double? weight { get; set; }
}
Then to add the unique key:
var mapper = new AllPropertiesMappingManager();
mapper.SetUniqueKey(typeof(Product).GetProperty("id"));



3.     Manual mapping

This allows you to programmatically define the field for each property:

public class Product {
    public string Id { get; set; }
    public string Manufacturer { get; set; }
    public ICollection Categories { get; set; }
    public decimal Price { get; set; }
    public bool InStock { get; set; }
    public DateTime Timestamp { get; set; }
    public double? Weight { get; set; }
}
var mgr = new MappingManager();
var property = typeof (Product).GetProperty("Id");
mgr.Add(property, "id");
mgr.SetUniqueKey(property);
mgr.Add(typeof(Product).GetProperty("Manufacturer"), "manu_exact");
mgr.Add(typeof(Product).GetProperty("Categories"), "cat_exact");
mgr.Add(typeof(Product).GetProperty("Price"), "price");
mgr.Add(typeof(Product).GetProperty("InStock"), "inStock");
mgr.Add(typeof(Product).GetProperty("Timestamp"), "timestamp");
mgr.Add(typeof(Product).GetProperty("Weight"), "weight");


二、建立 library

映射类以后, 必须初始化library来操作Solr instance. 通常在程序启动的时候运行一次:

Startup.Init("http://localhost:8983/solr");

然后需要 service locator for the SolrNet service instance 来进行操作:

var solr = ServiceLocator.Current.GetInstance>();
solr.Delete(SolrQuery.All)
    .Add(p)
    .Commit();
var products = solr.Query(new SolrQueryByRange("price", 10m, 100m));


 

三、查询

支持不同的查询方式:

1.     Simple query

Whatever you give it is passed straight to Solr's q parameter

ISolrOperations solr = ...

var products1 = solr.Query(new SolrQuery("lucene")); // search for "lucene" in the default field

var products2 = solr.Query(new SolrQuery("name:solr")); // search for "solr" in the "name" field


2.     Query by field

This allows you to define field name and value separately:

ISolrOperations solr = ...

var products = solr.Query(new SolrQueryByField("name", "solr")); // search for "solr" in the "name" field


It also has the benefit that it handles special character escaping for you.

3.     Query by range

Creates a range query:

ISolrOperations solr = ...

var products = solr.Query(new SolrQueryByRange("price", 100m, 250.50m)); // search for price between 100 and 250.50


4.     Query by list of values

var q = new SolrQueryInList("name", "solr", "samsung", "maxtor");

is the same as "name:solr OR name:samsung OR name:maxtor"


5.     "Any value" query

It's often convenient to see what documents have a field defined or not:

var q = new SolrHasValueQuery("name");


is equivalent to the Solr query "name:[* TO *]"

6.     Query operators

You can use the && and || operators to concatenate operators with the expected results:

var q = new SolrQuery("solr") && new SolrQuery("name:desc");

generates the query "solr AND name:desc"

The plus (+) operator is also overloaded.

var q = new SolrQuery("solr") + new SolrQuery("name:desc");


creates the query "solr name:desc"

To negate a query, you can call Not() on it or just use the '!' operator:

var q = !new SolrQuery("solr");


creates the query "-solr"

 

四、Facets 查询

SolrNet supports faceted searching.

There are basically three kinds of facet queries:

1. querying by field

2. date facets

3. arbitrary facet queries

Facet queries are issued through the FacetQueries property of QueryOptions. Then the QueryOptions instance is passed to the server instance.



1.     Querying by field

Querying by field is handled by the SolrFacetFieldQuery class. Results are available through the FacetFields property.

Example: print all categories sorted by popularity.

ISolrOperations solr = ...
var r = solr.Query(SolrQuery.All, new QueryOptions {
    Rows = 0,
    Facet = new FacetParameters {
        Queries = new[] {new SolrFacetFieldQuery("category")}
    }
});
foreach (var facet in r.FacetFields["category"]) {
  Console.WriteLine("{0}: {1}", facet.Key, facet.Value);
}



2.     Date facets

Date facet queries create facets from date ranges. Sample code:

ISolrOperations solr = ...
ISolrQueryResults results = solr.Query(SolrQuery.All, new QueryOptions {
    Facet = new FacetParameters {
        Queries = new[] {
            new SolrFacetDateQuery("timestamp", new DateTime(2001, 1, 1).AddDays(-1) /* range start */, new DateTime(2001, 1, 1).AddMonths(1) /* range end */, "+1DAY" /* gap */) {
                HardEnd = true,
                Other = new[] {FacetDateOther.After, FacetDateOther.Before}
            },
        }
    }
});
DateFacetingResult dateFacetResult = results.FacetDates["timestamp"];
foreach (KeyValuePair dr in dateFacetResult.DateResults) {
    Console.WriteLine(dr.Key);
    Console.WriteLine(dr.Value);
}


3.     Arbitrary facet queries

Arbitrary facet queries are handled by the SolrFacetQuery class. Results are available through the FacetQueries property.

Example: segregate items by price (less than $500 - more than $500)

ISolrOperations solr = ...
var lessThan500 = new SolrQueryByRange("price", 0m, 500m);
var moreThan500 = new SolrQueryByRange("price", "500", "*");
var r = solr.Query(SolrQuery.All, new QueryOptions {
    Rows = 0,
    Facet = new FacetParameters {
        Queries = new[] {new SolrFacetQuery(lessThan500), new SolrFacetQuery(moreThan500)}
    }
});
foreach (var facet in r.FacetQueries) {
  Console.WriteLine("{0}: {1}", facet.Key, facet.Value);
}



For an overview of faceted search with Solr, see SolrFacetingOverview.


五、高亮

Sample code:

var results = solr.Query(new SolrQueryByField("features", "noise"), new QueryOptions {
    Highlight = new HighlightingParameters {
        Fields = new[] {"features"},
    }
});
foreach (var h in results.Highlights[results[0]]) {
    Console.WriteLine("{0}: {1}", h.Key, h.Value);
}


 
would print for example:

features: NoiseGuard, SilentSeek technology, Fluid Dynamic Bearing (FDB) motor

Solr reference documentation: http://wiki.apache.org/solr/HighlightingParameters


六、More Like This

This option returns a list of similar documents for each document returned in the results of the original query.

Parameters are defined through the MoreLikeThis property of the QueryOptions

Example: searching for "apache", for each document in the result search for similar documents in the "cat" (category) and "manu" (manufacturer) fields:

ISolrBasicOperations solr = ...
var results = solr.Query(new SolrQuery("apache"), new QueryOptions {
    MoreLikeThis = new MoreLikeThisParameters(new[] {"cat", "manu"}) {
        MinDocFreq = 1, // minimum document frequency
        MinTermFreq = 1, // minimum term frequency
    },
});
foreach (var r in results.SimilarResults) {
    Console.WriteLine("Similar documents to {0}", r.Key.Id);
    foreach (var similar in r.Value)
        Console.WriteLine(similar.Id);
    Console.WriteLine();
}


All parameters defined in the Solr docs are supported.
 

七、拼写检查

You'll need to install the SpellCheckComponent in the standard request handler in order to use this.

Next, a spellcheck dictionary must be provided. Normally a default dictionary is created by invoking BuildSpellCheckDictionary() once per index:

ISolrOperations solr = ...

solr.BuildSpellCheckDictionary();


Now you can start issuing spellchecking queries by defining the SpellCheck parameter in the QueryOptions:

ISolrOperations solr = ...
var results = solr.Query("ipo appl", new QueryOptions {
  SpellCheck = new SpellCheckingParameters {Collate = true}
});

 

Then you get the suggestions from results.SpellChecking, i.e.:

foreach (var sc in results.SpellChecking) {
    Console.WriteLine("Query: {0}", sc.Query);
    foreach (var s in sc.Suggestions) {
        Console.WriteLine("Suggestion: {0}", s);                    
    }
}



which would print something like:

Query: ipo

Suggestion: ipod

Query: appl

Suggestion: apple


All of the SpellCheckComponent parameters are supported, except for the extendedResults option.


八、Stats

This feature provides you with simple statistics for numeric fields within the query results:

Sample usage:

ISolrOperations solr = ...
var results = solr.Query(SolrQuery.All, new QueryOptions {
    Rows = 0,
    Stats = new StatsParameters {
        Facets = new[] { "inStock" },
        FieldsWithFacets = new Dictionary> {
            {"popularity", new List {"price"}}
        }
    }
});
 
foreach (var kv in results.Stats) {
    Console.WriteLine("Field {0}: ", kv.Key);
    Console.WriteLine("Min: {0}", s.Min);
    Console.WriteLine("Max: {0}", s.Max);
    Console.WriteLine("Sum of squares: {0}", s.SumOfSquares);
    foreach (var f in s.FacetResults) {
        Console.WriteLine("Facet: {0}", f.Key);
        foreach (var fv in f.Value) {
            Console.WriteLine("Facet value: {0}", fv.Key);
            Console.WriteLine("Min: {0}", fv.Value.Min);
            Console.WriteLine("Max: {0}", fv.Value.Max);
            Console.WriteLine("Sum of squares: {0}", fv.Value.SumOfSquares);
        }
    }
}


相关文章

精彩推荐