SolrNet Documentation

October 12, 2017 | Author: Carlos Souto | Category: Xml Schema, Standard Deviation, Multi Core Processor, Information Retrieval, Apache Solr
Share Embed Donate


Short Description

SolrNet Documentation...

Description

1.

Overview and basic usage First, we have to map the Solr document to a class. Let's use a subset of the default schema that comes with the Solr distribution:

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; } }

It's just a POCO with some attributes: SolrField maps the attribute to a Solr field and SolrUniqueKey (optional but recommended) maps an attribute to a Solr unique key field. Now we'll write some tests using this mapped class. Let's initialize the library:

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

Let's add a document (make sure you have a running Solr instance before running this test): [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); solr.Commit(); }

Let's see if the document is where we left it: [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].Price); }

2.

Mapping Solr fields defined in your schema.xml must be mapped to properties in a .NET class. There are currently three built-in ways to map fields:

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")] // cat is a multiValued field 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;} // nullable property, it might not be defined on all documents. }

This way of mapping is implemented by the

AttributesMappingManager

class.

Index-time field boosting You can also use the mapping attribute to apply a boost to a specific field at indextime. [SolrField("inStock", Boost = 10.5)] public bool InStock { get; set; }

.. this will add a boost of 10.5 to the InStock field each time the document is indexed.

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"));

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");

Dictionary mappings and dynamic fields Solr dynamicFields can be mapped differently depending on the use case. They can be mapped "statically", e.g, given:

type="integer"

indexed="true"

a particular dynamicField instance can be mapped as:

[SolrField("price_i")] public decimal? Price {get;set;}

However, it's often necessary to have more flexibility. You can also map dynamicFields as a dictionary, with a field name prefix: [SolrField("price_")] public IDictionary Price {get;set;}

In this case, price_ is used as a prefix to the actual Solr field name, e.g. with this mapping,

Price["regular"]

maps to a Solr field named price_regular.

Another, even more flexible mapping: [SolrField("*")] public IDictionary OtherFields {get;set;}

This acts as a catch-all container for any fields that are otherwise unmapped. E.g.

OtherFields["price_i"]

maps to a Solr field named

price_i .

Fully loose mapping An even more "dynamic" mapping can be achieved by using a

Dictionary

as document type. In this document type, the dictionary

key corresponds to the Solr field name and the value to the Solr field value. Statically typing the fields is obviously lost in this case, though. When adding documents as

Dictionary

SolrNet will recognize field

value types as usual, e.g. you can use strings, int, collections, arrays, etc. Example: Startup.Init(serverUrl); var solr = ServiceLocator.Current.GetInstance();

solr.Add(new Dictionary { {"field1", 1}, {"field2", "something else"}, {"field3", new DateTime(2010, 5, 5, 12, 23, 34)}, {"field4", new[] {1,2,3}}, });

When fetching documents as

Dictionary

SolrNet will automatically

map each field value to a .NET type, but it's up to you to downcast the field value to a properly typed variable. Example: ISolrOperations solr = ... ICollection results = solr.Query(SolrQuery.All); bool inStock = (bool) results[0]["inStock"];

Custom mapping You can code your own mapping mechanism by implementing the

IReadOnlyMappingManager

interface.

Overriding the default mapper By default SolrNet maps Solr fields using attributes. However you might want to use another mapper. Replacing the default mapper depends on how you set up the library:

Built-in container If you're using the default built-in container, you can replace it like this before calling

Startup.Init() :

var mapper = new MappingManager();

/* Here come your mappings */ var container = new Container(Startup.Container); container.RemoveAll(); container.Register(c => mapper); ServiceLocator.SetLocatorProvider(() => container); Startup.Init("http://localhost:8983/solr");

Windsor facility If you're using the Windsor facility, you can override the mapper like this: var mapper = new MappingManager(); /* Here come your mappings */ var solrFacility = new SolrNetFacility("http://localhost:8983/solr") {Mapper = mapper}; var container = new WindsorContainer(); container.AddFacility("solr", solrFacility);

Ninject module var mapper = new MappingManager(); /* Here come your mappings */ var c = new StandardKernel(); c.Load(new SolrNetModule("http://localhost:8983/solr") {Mapper = mapper});

3. Initialization Once you have created your document class, you have to initialize the library in order to operate against the Solr instance. This is usually done once at application startup:

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

Then you ask the service locator for the SolrNet service instance which allows you to issue any supported operation: var solr = ServiceLocator.Current.GetInstance(); solr.Delete(SolrQuery.All); solr.Add(p); solr.Commit(); var products = solr.Query(new SolrQueryByRange("price", 10m, 100m));

Castle Windsor Alternatively, if your app uses Castle Windsor you can set up SolrNet using the included facility: container.AddFacility("solr", new SolrNetFacility("http://localhost:8983/solr"));

Or using Windsor's xml config: http://localhost:8983/solr

Ninject If you're using Ninject, you can use the Ninject module:

kernel.Load(new SolrNetModule("http://localhost:8983/solr"));

StructureMap If you are using StructureMap, you can use the StructureMap module ( StructureMap.SolrNetIntegration ): ObjectFactory.Initialize( x => x.AddRegistry( new SolrNetRegistry("http://localhost:8893/solr") ) );

Autofac (SolrNet 0.4.0) var builder = new ContainerBuilder(); builder.RegisterModule(new SolrNetModule("http://localhost:8983/solr")); var container = builder.Build();

Unity (SolrNet 0.4.0) var solrServers = new SolrServers { new SolrServerElement { Id = "test", Url = "htp://localhost:8893", DocumentType = typeof (Entity).AssemblyQualifiedName, }

}; container = new UnityContainer(); new SolrNetContainerConfiguration().ConfigureContainer(solrServers, container);

Multi-core mapping If you need to map multiple Solr cores/instances, see this page.

4. CRUD operations Create/Update Create and update are the same operation in Solr (and SolrNet). It's mapped to the

Add()

method in the

ISolrOperations interface.

There are two overloads of other takes a these

Add()

IEnumerable

Add() :

one takes a single document as parameter, the

of documents. Keep in mind that one call to any of

methods will end up in one HTTP request to Solr. So for example this:

ISolrOperations solr = ... for (var i = 0; i < 100; i++) solr.Add(new MyDocument(i));

is not the same as this: var documents = Enumerable.Range(0, 100).Select(i => new MyDocument(i)); solr.Add(documents);

If you

Add()

a document that already exists in the Solr index, it's replaced (using

the unique key as equality) There's also

AddWithBoost()

(also with single-document and

IEnumerable

overloads)

that you can use to apply an index-time boosting to the added documents. Add()

supports the

commitWithin

more information about them.

Retrieve

and

overwrite

parameters. See the Solr wiki for

See Querying

Delete The ISolrOperations interface has several

Delete()



Delete(T doc) :



Delete(string id) :



Delete(IEnumerable docs) :



Delete(IEnumerable ids) :



Delete(ISolrQuery q) :



Delete(IEnumerable ids, ISolrQuery q) :

overloads:

deletes a single document using its unique key to identify it. deletes a single document with a unique key deletes a batch of documents in a single shot. deletes a batch of documents in a single shot.

deletes all documents that match a query. deletes a batch of documents and all

documents that match a query in a single shot.

Commit and Optimize After issuing any number of

Add()

or

Delete()

operations, be sure to call

Commit() :

solr.Add(myDocument); solr.Add(anotherDocument); solr.Delete(oldDocument); solr.Commit();

... this tells Solr to finalise the changes you have made and to start rebuilding indexes and related data. Obviously this has a performance penalty on the Solr instance as all query caches are cleared and repopulated due to the new index. Alternatively, you can let Solr manage commits, enabling the autoCommit options in the Solr configuration. The

Optimize()

method:

solr.Optimize();

... issues a command to tell Solr to begin optimizing its indexes. Again this is an expensive operation in terms of the Solr instance and shouldn't be called too frequently. Additional information on committing and optimization considerations can be found here

Rollback Rollback()

rollbacks all add/deletes made to the index since the last commit. Note

that this is nothing like the rollback of relational databases. See the Solr wiki for more information.

5. Querying Simple query This is the simplest 'query object' in SolrNet. 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

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. (SolrNet 0.4.0) You can disable character escaping by setting

Quoted = false :

var q = new SolrQueryByField("name", "John*") { Quoted = false };

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

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

"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 *]

Query by distance (SolrNet 0.4.0) Creates a

geofilt

or

bbox

filter on a LatLonType field.

Examples: // default accuracy is CalculationAccuracy.Radius (higher accuracy) var q = new SolrQueryByDistance("store", pointLatitude = 45.15, pointLongitude = 93.85, distance = 5); var q = new SolrQueryByDistance("store", pointLatitude = 45.15, pointLongitude = 93.85, distance = 5, accuracy = CalculationAccuracy.BoundingBox);

See the Solr wiki for more information.

Query operators You can use the

&&

and

||

operators to connect queries, 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. It concatenates the queries and leaves the actual operator to the default as specified in Solr's configuration. 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

Finally, the minus (-) operator: var q = new SolrQuery("solr") - new SolrQuery("name:desc"); // solr - name:desc

which is equivalent to (and more intuitive than): var q = new SolrQuery("solr") + !new SolrQuery("name:desc"); // solr - name:desc

Alternatively, if you have a list of queries you want to aggregate you can use

SolrMultipleCriteriaQuery .

For example:

new SolrMultipleCriteriaQuery(new[] {new SolrQuery("1"), new SolrQuery("2")})

is the same as: new SolrQuery("1") + new SolrQuery("2")

You can also define what operators to use to join these queries, e.g: new SolrMultipleCriteriaQuery(new[] {new SolrQuery("1"), new SolrQuery("2")}, "AND")

Boosting You can boost particular queries by calling

Boost() ,

for example:

var q = new SolrQuery("name:desc").Boost(2); // (name:desc)^2

See the Lucene docs for more information about boosting.

DSL See the fluent API documentation for an alternative way of expressing queries.

Filter queries Filter queries can be used to specify a query that can be used to restrict the super set of documents that can be returned, without influencing score. ISolrOperations solr = ... var products = solr.Query(SolrQuery.All, new QueryOptions { FilterQueries = new ISolrQuery[] { new SolrQueryByField("manu", "apache"), new SolrQueryByRange("price", 100m, 200m), } });

More information in the Solr wiki.

Fields By default Solr returns all stored fields. You can retrieve only selected fields instead: ISolrOperations solr = ... var products = solr.Query(SolrQuery.All, new QueryOptions { Fields = new[] {"id", "manu"} });

Sorting

By default Solr returns search results ordered by "score desc". You can sort the results by any field(s): ISolrOperations solr = ... var products = solr.Query(SolrQuery.All, new QueryOptions { OrderBy = new[] {new SortOrder("manu", Order.DESC), SortOrder.Parse("id asc")} });

You can random sort using

RandomSortOrder :

solr.Query(SolrQuery.All, new QueryOptions { OrderBy = new[] {new RandomSortOrder("randomF")}, });

where

randomF

is a random sort field.

RandomSortOrder

has various constructors to

generate a random seed (as in the example above) or use a predefined seed.

Pagination In Solr you can't retrieve all your documents in single query. However, by default SolrNet will try to retrieve a large amount of documents, trying to mimic the behavior of a RDBMS without a TOP clause. It's not recommended to rely on this behavior. Instead, always define pagination parameters, for example: ISolrOperations solr = ... solr.Query("somequery", new QueryOptions{ Start = 10, Rows = 25 });

This will fetch at most 25 documents, starting from the 10th document in the total result set.

Additional parameters Solr has lots of features that aren't directly mapped in SolrNet, but you can enable and use most of them with the

ExtraParams dictionary.

Parameters defined

in

ExtraParams

are directly passed to the Solr querystring. For example you

can restrict the maximum time allowed for a query: ISolrOperations solr = ... var products = solr.Query(SolrQuery.All, new QueryOptions { ExtraParams = new Dictionary { {"timeAllowed", "100"} } });

Or enable DisMax instead of the standard request handler: ISolrOperations solr = ... var products = solr.Query(SolrQuery.All, new QueryOptions { ExtraParams = new Dictionary { {"qt", "dismax"} } });

LocalParams LocalParams provide a way to add certain metadata to a piece of query. It's used among other things to change the default operator type on the fly for a particular query. In SolrNet, LocalParams are represented by the basically a

Dictionary .

LocalParams

class, which is

LocalParams are attached to a query using

the "+" operator. Here's an example: solr.Query(new LocalParams {{"type", "dismax"},{"qf", "myfield"}} + new SolrQuery("solr rocks"));

This will generate:

q={!type=dismax qf=myfield}solr rocks

More information about LocalParams in the Solr wiki.

6. Faceting 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 the

QueryOptions

FacetQueries

property of

QueryOptions .

Then

instance is passed to the server instance.

Querying by field Querying by field is handled by the through the

FacetFields

SolrFacetFieldQuery

class. Results are available

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); }

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

var 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); }

Arbitrary facet queries Arbitrary facet queries are handled by the available through the

FacetQueries

SolrFacetQuery

class. Results are

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); }

Pivot faceting http://wiki.apache.org/solr/HierarchicalFaceting#Pivot_Facets http://wiki.apache.org/solr/SimpleFacetParameters#Pivot_.28ie_Decision_Tree.29 _Faceting (to be documented)

7. Highlighting This feature will "highlight" (typically with markup) the terms that matched the query, including a snippet of the text around the matched term. 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].Id]) { Console.WriteLine("{0}: {1}", h.Key, string.Join(", ", h.Value.ToArray())); }

would print for example: features: NoiseGuard, SilentSeek technology, Fluid Dynamic Bearing (FDB) motor

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

8. More-like-this This feature 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.

9. Spell checking 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()

at commit/optimize time (you can

also configure Solr to automatically rebuild spellchecking indices): 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 ,

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

i.e.:

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

10.

option.

Stats

Property

Description

Min

The minimum value

Max

The maximum value

Sum

Sum of all values

Count

How many (non-null) values

Missing

How many null values

Property

Description

SumOfSquares

Sum of all values squared (useful for stddev)

Mean

The average (v1+v2...+vN)/N

Standard Deviation -- measuring how widely spread the

StdDev

values in a data set are.

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); var s = kv.Value;

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); } } }

For more details see the Solr wiki.

11.

Field collapsing / grouping

This feature can be used to collapse - or group - documents by the unique values of a specified field. Included in the results are the number of records by document key and by field value.

For Solr 1.4 / 3.1 This feature is not included with the stock Solr 1.4 or 3.1. You need to apply a patch and recompile Solr. Sample code: ISolrOperations solr = ...

var results = solr.Query(new SolrQueryByField("features", "noise"), new QueryOptions { Collapse = new CollapseParameters { Field = "manu" } }); foreach (KeyValuePair collapsedDocument in results.Collapsing.DocResults) Console.WriteLine("Collapse count for document '{0}': {1}", collapsedDocument.Key, collapsedDocument.Value);

For more details see: 

http://wiki.apache.org/solr/FieldCollapsing



https://issues.apache.org/jira/browse/SOLR-236



http://blog.jteam.nl/2009/10/20/result-grouping-field-collapsing-with-solr/

For Solr 3.3+ Use

Grouping

instead of

Collapse

in

QueryOptions

with SolrNet 0.4.0 alpha 1 or

later. Sample code

12.

Core admin

SolrNet offers some facilities to execute Solr core admin commands. See the Solr wiki for detailed explanations of these commands. First, build an instance of

ISolrCoreAdmin :

const string solrUrl = "http://localhost"8983/solr"; var headerParser = ServiceLocator.Current.GetInstance(); var statusParser = ServiceLocator.Current.GetInstance(); ISolrCoreAdmin solrCoreAdmin = new SolrCoreAdmin(new SolrConnection(solrUrl), headerParser, statusParser); ISolrCoreAdmin

can execute the following core admin commands:

Status /// Get the status of all registered cores: IList coreStatus = solrCoreAdmin.Status(); /// Get the status of a single core: var coreStatus = solrCoreAdmin.Status("core1");

Create solrCoreAdmin.Create(coreName: "items", instanceDir: "items");

Reload solrCoreAdmin.Reload("core1");

Rename solrCoreAdmin.Rename("core1", "newCoreName");

Swap solrCoreAdmin.Swap("core0", "core1");

Unload solrCoreAdmin.Swap("core0", UnloadCommand.Delete.Data);

Merge solrCoreAdmin.Merge("destinationCore", new MergeCommand.SrcCore("sourceCore0"), new MergeCommand.SrcCore("sourceCore1"));

Alias solrCoreAdmin.Alias("existingCore", "alias");

13.

Fluent API

Query-building Some examples: Query.Simple("name:solr"); // name:solr Query.Field("name").Is("solr"); // name:solr Query.Field("price").From(10).To(20); // price:[10 TO 20] Query.Field("price").In(10, 20, 30); // price:10 OR price:20 OR price:30 Query.Field("name").HasAnyValue(); // name:[* TO *]

These can be used anywhere where a

ISolrQuery

is accepted, e.g.:

ISolrOperations solr = ... solr.Query(Query.Field("name").HasAnyValue());

They can also be mixed with boolean operators: ISolrOperations solr = ... solr.Query(Query.Field("name").HasAnyValue() && Query.Field("price").Is(0));

Querying This API is deprecated. Please don't use it. If you're using it, be aware that it will be removed in a future release of SolrNet. Example: [SetUp] public void setup() { Solr.Connection = new SolrConnection("http://localhost:8983/solr"); }

[Test] public void QueryById() { ISolrQueryResults r = Solr.Query().By("id").Is("123456").Run(); }

[Test] public void QueryByRange() { ISolrQueryResults r = Solr.Query().By("id").Between(123).And(456).OrderBy("id", Order.ASC).Run(); }

[Test] public void DeleteByQuery() { Solr.Delete.ByQuery("id:123456");

}

Run()

is the explicit kicker method. There are some more examples in the tests.

14.

Overriding the default mapper

By default SolrNet maps Solr fields using attributes. However you might want to use another mapper. Replacing the default mapper depends on how you set up the library:

Built-in container If you're using the default built-in container, you can replace it like this before calling

Startup.Init() :

var mapper = new MappingManager(); /* Here come your mappings */ var container = new Container(Startup.Container); container.RemoveAll(); container.Register(c => mapper); ServiceLocator.SetLocatorProvider(() => container); Startup.Init("http://localhost:8983/solr");

Windsor facility If you're using the Windsor facility, you can override the mapper like this: var mapper = new MappingManager(); /* Here come your mappings */ var solrFacility = new SolrNetFacility("http://localhost:8983/solr") {Mapper = mapper}; var container = new WindsorContainer();

container.AddFacility("solr", solrFacility);

Ninject module var mapper = new MappingManager(); /* Here come your mappings */ var c = new StandardKernel(); c.Load(new SolrNetModule("http://localhost:8983/solr") {Mapper = mapper});

15.

NHibernate-SolrNet integration

A NHibernate-SolrNet module is included in SolrNet, with these features: 

Automatic database -> Solr synchronization



Issue Solr queries from NHibernate's ISession This is intended to be used on entities that are similarly mapped on both NHibernate and SolrNet. This integration is deprecated. It is not generic enough to be truly reusable for most non-trivial cases. It will be removed in a future release of SolrNet.

Setup Configure SolrNet and NHibernate as usual. Then apply SolrNet's integration to NHibernate's configuration like this: NHibernate.Cfg.Configuration cfg = SetupNHibernate(); var cfgHelper = new NHibernate.SolrNet.CfgHelper(); cfgHelper.Configure(cfg, true); // true -> autocommit Solr after every operation (not really recommended)

If you're not using the default built-in container, you have to tell e.g.:

CfgHelper

to use it,

IWindsorContainer container = new WindsorContainer(); ... var cfgHelper = new NHibernate.SolrNet.CfgHelper(container); ...

Usage Whenever a NHibernate entity that is also mapped in SolrNet is created, updated, or deleted, it will be automatically updated on Solr. NHibernate transactions are honored: entities are updated on Solr only when the NHibernate transaction is committed. This synchronization goes only in the direction NHibernate -> SolrNet, not the other way around, i.e. operations issued directly through ISolrOperations will not be reflected on NHibernate. In order to issue Solr queries through NHibernate, the ISession needs to be wrapped. Sample: ISessionFactory sessionFactory = ... using (var session = cfgHelper.OpenSession(sessionFactory)) { ICollection entities = session.CreateSolrQuery("this is a fulltext query").SetMaxResults(10).List(); }

16.

Multi-core / multi-instance

This page describes how to configure SolrNet to access (read/write) multiple Solr cores or instances. It assumes you know what Solr cores are, how to configure and use them outside of SolrNet. This page doesn't cover CoreAdminHandler commands.

How to configure SolrNet for multicore depends on how it's integrated to your app, and if your cores map to different types or the same type.

With built-in container The built-in container ( Startup ) is currently limited to access multiple cores/instances with different mapped types. It's quite simple to configure: assuming you have a core that maps to class Product and another core mapping to class

Person :

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

ISolrOperations solrProduct = ServiceLocator.Current.GetInstance(); solrProduct.Add(new Product { Name = "Kodak EasyShare" }); solrProduct.Commit();

ISolrOperations solrPerson = ServiceLocator.Current.GetInstance(); solrPerson.Add(new Person { FirstName = "Joe", LastName = "Example" }); solrPerson.Commit();

With Windsor facility Code config: var solrFacility = new SolrNetFacility("http://localhost:8983/solr/defaultCore"); solrFacility.AddCore("core0-id", typeof(Product), "http://localhost:8983/solr/product");

solrFacility.AddCore("core1-id", typeof(Product), "http://localhost:8983/solr/product2"); solrFacility.AddCore(typeof(Person), "http://localhost:8983/solr/person"); // no need to set an explicit ID since it's the only core for Person container.AddFacility("solr", solrFacility);

ISolrOperations solrPerson = container.Resolve(); ISolrOperations solrProduct1 = container.Resolve("core0-id"); // use proper Windsor service overrides instead of resolving like this ISolrOperations solrProduct2 = container.Resolve("core1-id");

Equivalent XML config: http://localhost:8983/solr/defaultCore Namespace.To.Product, MyAssembly http://localhost:8983/solr/product Namespace.To.Product, MyAssembly http://localhost:8983/solr/product2 Namespace.To.Person, MyAssembly http://localhost:8983/solr/person

With StructureMap registry

var cores = new SolrServers { new SolrServerElement { Id = "core0-id", DocumentType = typeof(Product).AssemblyQualifiedName, Url = "http://localhost:8983/solr/product", }, new SolrServerElement { Id = "core1-id", DocumentType = typeof(Person).AssemblyQualifiedName, Url = "http://localhost:8983/solr/person", }, }; ObjectFactory.Initialize(c => c.IncludeRegistry(new SolrNetRegistry(cores))); var solr1 = ObjectFactory.GetInstance(); var solr2 = ObjectFactory.GetInstance();

Equivalent XML config (in App.config):



17.

Schema/mapping validation

SolrNet aims to be flexible to map a Solr schema in different ways depending on the project needs. A single schema may be mapped in several different ways even within a single project. However, there are invalid mappings that will end up in runtime errors, and it may not be evident from these errors that the problem lies in the mapping. SolrNet offers a facility to aid with the detection of mapping mismatches. Example: ISolrOperations solr = ... IList mismatches = solr.EnumerateValidationResults().ToList(); var errors = mismatches.OfType(); var warnings = mismatches.OfType(); foreach (var error in errors) Console.WriteLine("Mapping error: " + error.Message); foreach (var warning in warnings) Console.WriteLine("Mapping warning: " + warning.Message);

if (errors.Any()) throw new Exception("Mapping errors, aborting");

18.

Sample application

A sample web application is provided to demo some of the library's features. This sample application is not meant to be an absolute reference of SolrNet integration with your application. Real world applications are likely to need much more complex interactions with SolrNet. Screenshot:

Requirements: 

.NET 3.5 SP1



ASP.NET MVC 2.0



Java 1.5 or better

After downloading and extracting the sample app, run

runsample.bat

to fire up the

included Solr and Cassini.

19. Frequently asked questions about SolrNet Is SolrNet a .NET port of Solr? No, SolrNet is a HTTP client so you can talk to Solr from your .NET application. If you want to run Solr on .NET, take a look at thisblog post.

What version of Solr do I need? Does SolrNet work with the latest release of Solr? It's very uncommon for Solr to make breaking changes in core functionality between releases, so SolrNet should work with any fairly recent version of Solr (3.1+). Note that it's up to you to use features that are supported by your Solr version. For example, you will get an error if you try to use grouping with Solr 3.1

I'm getting a Bad Request error when calling

Commit()

You're probably using an outdated version. Upgrade to a recent build

I'm getting a 404 (not found) response from Solr when doing any operation with SolrNet You're probably missing the core name in the URL you're passing to Startup.Init

I'm getting an error "'SolrConnection' already registered in container" Make sure you call

Startup.Init

only once per document type in your application.

I created my SolrNet document type, but when I add an instance to Solr I get an 'unknown field' error. You need to edit the schema.xml in Solr to reflect the fields mapped in your .NET document type. Schema reference: 

http://wiki.apache.org/solr/SchemaXml



https://cwiki.apache.org/confluence/display/solr/Overview+of+Documents,+Fields,+ and+Schema+Design You can also use the schema/mapping validation for guidance.

How do I get the

score

pseudo-field?

Solr does not return the score by default, so you have to fetch it explicitly. In SolrNet this translates to

Fields = new[] {"*","score"}

in your

QueryOptions

instance.

Also, you have to map it to a property in your document type. For example: [SolrField("score")] double? Score { get; set; }

I'm getting a "URI too long" error You're hitting the GET request limit of the Solr web container (i.e. Jetty or Tomcat). You can either: 

edit this limit in the web container configuration, or



make SolrNet use POST instead of GET. You can do this by installing the SolrNet.Impl.PostSolrConnection decorator (here's an example)

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF