Wiki source code of Solr Integration

Last modified by Vincent Massol on 2024/11/19 16:12

Show last authors
1 {{include document="XWiki.DesignClassSheet"/}}
2
3 = Introduction =
4
5 The goal of this document is to start a discussion about how to integrate SOLR as a search engine for XWiki.
6
7 SOLR is a search platform that is built on top of Lucene. It supports full-text search, hit highlighting, faceted search, dynamic clustering, database integration, rich document (e.g., Word, PDF) handling, and geospatial search. It uses a plugin architecture that allows the administrator to setup different type of analysers by combining tokenizers, filters etc. All of this is done declaratively using XML configuration files.
8
9 SOLR is distributed as a web application (WAR) that needs to be installed in a servlet container and used via a HTTP protocol. However an [[EmbeddedSolrServer>>http://wiki.apache.org/solr/Solrj#EmbeddedSolrServer]] is also available which allows to start a SOLR core from within an application.
10
11 = Configuration =
12
13 SOLR needs to be configured using two XML files:
14
15 * ##solrconfig.xml## which contains the handlers that will take care of indexing and searching documents
16 * ##schema.xml## which defines the structure of what is stored in the index.
17
18 The following links show the default version of [[solrconfig.xml>>http://svn.apache.org/repos/asf/lucene/dev/trunk/solr/example/solr/conf/solrconfig.xml]] and [[schema.xml>>http://svn.apache.org/viewvc/lucene/dev/trunk/solr/example/solr/conf/schema.xml?view=co&revision=1141489&content-type=text%2Fplain]]
19
20 Actually the ##schema.xml## is tailored on an example provided with the SOLR distribution, but it is interesting because it contains a big section with field types definition that can be reused in other contexts.
21
22 ##solrconfig.xml## and ##schema.xml## are searched in the classpath so they can be packaged with a SOLR component. What could be interesting is to provide a way for override the ##schema.xml## with a version that contains specific customization for a specific use case. For example, the default ##schema.xml## contains analysers that are well suited for analysing english text. It would be nice to have a way for overriding this and use language specific tokenizers when needed.
23
24 = Queries =
25
26 The standard SOLR query parser is a superset of the Lucene query parser that supports:
27
28 * Range queries
29 * Negative queries
30
31 SOLR also supports faceted queries that allow to cluster results with respect to some criteria.
32
33 Let's suppose that we have indexed three documents:
34
35 * ##id="Main.WebHome",title="Test",author="fm",date="2010-10-10"##
36 * ##id="Main.Test",title="foo",author="fm",date="2010-11-10"##
37 * ##id="Main.Bar",title="bar",author="xw",date="2011-03-30"##
38
39 ##id##, ##title##, ##author## and ##date## are fields defined in the ##schema.xml## with the proper data types.
40
41 Here is some interesting queries:
42
43 ##title:?e*## (all the documents whose title has an #e# as the second character); Result -> ##Main.WebHome##, ##Main.Test##
44 ##-author:fm## (all the documents that have not been written by ##fm##); Result -> ##Main.Bar##
45 ##date:[2010-10-01T00:00:00Z TO 2010-12-01T00:00:00Z]## (all the documents written between the 1st October 2010 and the 1st december 2010); Result -> ##Main.WebHome##, ##Main.Test##
46
47 We could also ask to cluster documents using ##author## as the facet field.
48
49 In this case, depending on the query, a clustering information about how many documents in the result are associated to an author will be also provided.
50
51 * ##facet="author", date:[2010-10-01T00:00:00Z TO 2010-12-01T00:00:00Z]## -> ##Main.WebHome##, ##Main.Test##, ##[author:[fm (2), xw (0)]]##
52 * ##facet="author", *:*## -> ##Main.WebHome##, ##Main.Test##, ##Main.Bar##, ##[author:[fm (2), xw (1)]]##
53
54 Since the standard query parser is a superset of the Lucence query parser, all Lucene queries will also work using this parser.
55
56 It is to be noted that the parser can also be replaced. The SOLR distribution provides additional query parsers that could be used in specific situations (see [[subclasses of the QParserPlugin>>http://lucene.apache.org/solr/api/org/apache/solr/search/QParserPlugin.html]]
57
58 == Example code ==
59
60 Here it is a sample code that shows how to startup an EmbeddedSolrServer and perform some queries.
61
62 {{code language="java"}}
63 CoreContainer.Initializer initializer = new CoreContainer.Initializer();
64 CoreContainer container = initializer.initialize();
65 EmbeddedSolrServer solr = new EmbeddedSolrServer(container, "");
66
67 solr.deleteByQuery( "*:*" );
68
69 SolrInputDocument doc = new SolrInputDocument();
70 doc.addField("id", "Main.WebHome");
71 doc.addField("title", "Welcome to the wiki");
72 doc.addField("content", "foo");
73 doc.addField("author", "fm");
74 doc.addField("date", new GregorianCalendar(2010, 9, 10).getTime());
75 solr.add(doc);
76
77 doc = new SolrInputDocument();
78 doc.addField("id", "Main.Test");
79 doc.addField("title", "Test");
80 doc.addField("content", "bar");
81 doc.addField("author", "fm");
82 doc.addField("date", new GregorianCalendar(2010, 10, 10).getTime());
83 solr.add(doc);
84
85 doc = new SolrInputDocument();
86 doc.addField("id", "Main.Bar");
87 doc.addField("title", "bar");
88 doc.addField("content", "bar");
89 doc.addField("author", "xw");
90 doc.addField("date", new GregorianCalendar(2011, 03, 03).getTime());
91 solr.add(doc);
92
93 solr.commit();
94
95 SolrQuery query = new SolrQuery();
96 query.setQuery("date:[2010-10-01T00:00:00Z TO 2010-12-01T00:00:00Z]").
97 setFacet(true).
98 addFacetField("author").
99 setSortField("title", SolrQuery.ORDER.asc);
100
101 QueryResponse response = solr.query(query);
102
103 System.out.format("%s\n", response.getFacetFields());
104
105 for(SolrDocument d : response.getResults()) {
106 System.out.format("%s %s\n", d.getFieldValue("title"), d.getFieldValue("date"));
107 }
108 {{/code}}
109
110 = XWiki integration =
111
112 Currently the search feature is provided by a Lucene plugin that contains all the logic for indexing, reindexing and querying the Lucene index.
113 The idea is to move this to a Wiki component in order to get rid of the plugin.
114
115 I created a small prototype which only starts the SOLR embedded server at startup and that is built using Java components.
116 You can find it here: [[https://github.com/fmancinelli/xwiki-platform/tree/SOLR/xwiki-platform-core/xwiki-platform-search]]
117
118 [[xwiki-platform-search-api>>https://github.com/fmancinelli/xwiki-platform/tree/SOLR/xwiki-platform-core/xwiki-platform-search/xwiki-platform-search-api]] defines the API of a ##SearchService## and its script service. This is the component that will be used for performing searches. In principle it could have the same API exposed by the plugin.
119
120 [[xwiki-platform-search-solr>>https://github.com/fmancinelli/xwiki-platform/tree/SOLR/xwiki-platform-core/xwiki-platform-search/xwiki-platform-search-solr]], on the other hand, contains the actual implementation of the API based on SOLR. At the moment it only starts up the ##EmbeddedSolrServer##
121
122 The backend to be used can be configured using the ##xwiki.cfg##
123
124 An open question is whether we need this flexibility of we can choose to use SOLR as the default and only search engine.
125
126 ----
127
128 In the [[discussion on the mailing list>>http://markmail.org/message/afeup6bsnz4jxg5a]], Paul Libbrecht suggested to use the DisMax handler and query parser for parsing queries. The DisMax handler is " is designed to process simple user entered phrases (without heavy syntax) and search for the individual words across several fields using different weighting (boosts) based on the significance of each field, and it should never throw an exception." ([[http://wiki.apache.org/solr/DisMax]])
129
130 It can be tweaked by specifying the weights to assign to the different fields.
131
132 For the schema Paul suggested something like:
133
134 * text: full-text, exact tokens (whitespace analyzer)
135 * text_standard: full-text, standard-analyzer (e.g. best for emails and URLs)
136 * text_fr: stemmed with the french analyzer (filled if the document is recognized to be french)
137 * text_de: ...
138 * text_bits: makes any non-letter a token separator
139 Same with title_*
140
141 With a standard qf = title^3 title_standard^2 title_fr^1.5 title_en^1.5 title_de^1.5 title_bits^1.2 text^3 text_standard^2 text_fr^1.5 text_en^1.5 text_de^1.5 text_bits^1.2
142
143 Dynamic fields might be used for handling translations: *_fr : text_fr.
144
145 At the UI level everything stays the same but a checkbox that activates a text-field for entering a custom qf could be added.
146
147 Facets handling/displaying is still to be investigated.
148
149 As another suggestion, Paul said to integrate highlighting in the results (SOLR can provide text highlight spans as part of the results)

Get Connected