Skip to content

Commit f0fab73

Browse files
ShazwazzaCopilot
andauthored
Update docs for v4.0.0 and fix the DocFX publishing pipeline (#588)
The docs site has not deployed since 2023-03-08 and the content on `dev` had drifted from the v4 API. Publishing pipeline: - Trigger `docfx-gh-pages.yml` on push/PR to `dev` (scoped to `docs/**`, `src/**` and the workflow file) instead of `feature/docfx`, which never fired. Keep `workflow_dispatch`. - Install the .NET 8/9/10 SDKs. The DocFX `metadata` step MSBuild-loads `src/**.csproj`, which now multi-targets net8.0;net9.0;net10.0, so the pinned .NET 6 SDK could not restore or build it. - Replace `nunit/docfx-action@v2.10.0` with `dotnet tool install -g docfx` so the `modern` template builds against a current DocFX. - Bump `actions/checkout` v3 -> v7, `actions/setup-dotnet` v3 -> v6, `actions/configure-pages` v3 -> v6, `actions/upload-pages-artifact` v1 -> v5 and `actions/deploy-pages` v1 -> v5. The v1 Pages actions are retired. - Guard the `deploy` job so pull requests build but do not publish. - Point `_gitContribute.branch` at `dev` so "Edit this page" links resolve, and exclude `Examine.Benchmarks` from API reference generation. Content: - index.md: correct the Minimum Requirements table (V4 is .NET 8.0/9.0/10.0, V3 is .NET 6.0/8.0 - it was claiming .NET Standard 2.0), correct the install version to 4.0.0, and add a "What's new in V4" section linking to the v3-to-v4 API change report and the release notes. - configuration.md: rewrite the facet and taxonomy registration samples. They used `facetsConfig:` and `useTaxonomyIndex:` named parameters on `AddExamineLuceneIndex` that do not exist; these are properties on `LuceneIndexOptions`. Replace the v3-era "After construction" section, which used a removed `LuceneIndex` constructor and a `FieldDefinitionCollection` that is no longer publicly mutable. Note that `UseTaxonomyIndex` defaults to true. Document the NRT options, `IndexDeletionPolicy`, `UnlockIndex` and `DirectoryFactory`. - searching.md: rewrite the Faceting section - every sample called `facets.Facet(...)`, which does not exist; the API is `FacetString`, `FacetLongRange`, `FacetDoubleRange` and `FacetFloatRange`. Cover `GetFacets()`, `TryGetFacet` and nullable results, and taxonomy-side faceting. Fill in the "Booleans, Groups & Sub Groups" section, which was a TODO. Document `SelectField`/`SelectFields`/`SelectAllFields`, `WithBoost` and `Phrase()`. - paging.md: document deep paging with `SearchAfterOptions` and `ExecuteWithLucene`, plus skip/take limits, scoring options and facet sampling. Correct `DefaultMaxResults` from 500 to 100. - Replace `indexer.GetSearcher()` with the `Searcher` property throughout. - Fix several samples that assigned `CreateQuery()` to a variable and then called `Or()`, `And()` or `Execute()` on it. `IQuery` exposes none of those - they are on `IBooleanOperation`, so the samples did not compile. - Add replication.md covering `ExamineReplicator`, taxonomy replication, scheduled replication and `IsReplicationHealthy`. Replication had no documentation. - developerguides: correct the project paths in codestructure.md, add `Examine.Benchmarks`, note the .NET 10 SDK requirement in buildtest.md, clean up the DocFX build instructions in docsite.md and add the 4.0.0 GA entry to roadmap.md. - Sweep stale links: Lucene.NET `4.8.0-beta00016` -> `4.8.0-beta00018` (the dependency did not change in v4, the docs were just wrong), and `blob/master` / `blob/release/3.0` source links -> `blob/dev`. Every code sample was compiled against the v4 assemblies to verify it uses real APIs. `docs/docs-v1-v2/` is intentionally left untouched. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent c950728 commit f0fab73

14 files changed

Lines changed: 603 additions & 214 deletions

File tree

.github/workflows/docfx-gh-pages.yml

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,18 @@ name: Deploy DocFX with GitHub Pages dependencies preinstalled
33
on:
44
# Runs on pushes targeting the default branch
55
push:
6-
branches: ["feature/docfx"]
6+
branches: ["dev"]
7+
paths:
8+
- 'docs/**'
9+
- 'src/**'
10+
- '.github/workflows/docfx-gh-pages.yml'
711
pull_request:
812
branches:
9-
- 'feature/docfx'
13+
- 'dev'
14+
paths:
15+
- 'docs/**'
16+
- 'src/**'
17+
- '.github/workflows/docfx-gh-pages.yml'
1018

1119
# Allows you to run this workflow manually from the Actions tab
1220
workflow_dispatch:
@@ -28,24 +36,33 @@ jobs:
2836
runs-on: ubuntu-latest
2937
steps:
3038
- name: Checkout
31-
uses: actions/checkout@v3
32-
- name: Instal DotNet
33-
uses: actions/setup-dotnet@v3
39+
uses: actions/checkout@v7
40+
- name: Install DotNet
41+
uses: actions/setup-dotnet@v6
3442
with:
35-
dotnet-version: '6.0.x'
43+
# DocFX builds the API reference from src/**.csproj, which multi-targets
44+
# net8.0;net9.0;net10.0, so every targeted SDK must be present.
45+
dotnet-version: |
46+
8.0.x
47+
9.0.x
48+
10.0.x
3649
- name: Setup Github Pages
37-
uses: actions/configure-pages@v3
50+
uses: actions/configure-pages@v6
51+
- name: Install DocFX
52+
run: |
53+
dotnet tool install -g docfx
54+
echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH"
3855
- name: Build DocFX Site
39-
uses: nunit/docfx-action@v2.10.0
40-
with:
41-
args: docs/docfx.json
56+
run: docfx docs/docfx.json
4257
- name: Upload docfx built site artifact
43-
uses: actions/upload-pages-artifact@v1
58+
uses: actions/upload-pages-artifact@v5
4459
with:
4560
path: docs/_site
4661

4762
# Deployment job
4863
deploy:
64+
# Never deploy from a pull request, only from pushes and manual runs
65+
if: github.event_name != 'pull_request'
4966
environment:
5067
name: github-pages
5168
url: ${{ steps.deployment.outputs.page_url }}
@@ -54,4 +71,4 @@ jobs:
5471
steps:
5572
- name: Deploy to GitHub Pages
5673
id: deployment
57-
uses: actions/deploy-pages@v1
74+
uses: actions/deploy-pages@v5

docs/articles/configuration.md

Lines changed: 68 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ Configuration of Examine indexes is done with [.NET's Options pattern](https://d
2525
There are several options that can be configured, the most common ones are:
2626

2727
* __FieldDefinitions__ _[`FieldDefinitionCollection`](xref:Examine.FieldDefinitionCollection)_ - Manages the mappings between a field name and it's index value type
28-
* __Analyzer__ _`Analyzer`_ - The default Lucene Analyzer to use for each field (default = [`StandardAnalyzer`](https://lucenenet.apache.org/docs/4.8.0-beta00016/api/analysis-common/Lucene.Net.Analysis.Standard.StandardAnalyzer.html))
29-
* __Validator__ _[`IValueSetValidator`]([`IValueSetValidator`](xref:Examine.IValueSetValidator))_ - Used to validate a value set to be indexed, if validation fails it will not be indexed
28+
* __Analyzer__ _`Analyzer`_ - The default Lucene Analyzer to use for each field (default = [`StandardAnalyzer`](https://lucenenet.apache.org/docs/4.8.0-beta00018/api/analysis-common/Lucene.Net.Analysis.Standard.StandardAnalyzer.html))
29+
* __Validator__ _[`IValueSetValidator`](xref:Examine.IValueSetValidator)_ - Used to validate a value set to be indexed, if validation fails it will not be indexed
3030
* __[IndexValueTypesFactory](xref:Examine.Lucene.IFieldValueTypeFactory)__ _`IReadOnlyDictionary<string, IFieldValueTypeFactory>`_ - Allows you to define custom Value Types
3131

3232
```cs
@@ -35,7 +35,7 @@ There are several options that can be configured, the most common ones are:
3535
/// </summary>
3636
public sealed class ConfigureIndexOptions : IConfigureNamedOptions<LuceneDirectoryIndexOptions>
3737
{
38-
public void Configure(string name, LuceneDirectoryIndexOptions options)
38+
public void Configure(string? name, LuceneDirectoryIndexOptions options)
3939
{
4040
switch (name)
4141
{
@@ -52,39 +52,22 @@ public sealed class ConfigureIndexOptions : IConfigureNamedOptions<LuceneDirecto
5252
}
5353
```
5454

55-
### After construction
55+
### At registration
5656

57-
You can modify the field definitions [FieldDefinitionCollection](xref:Examine.FieldDefinitionCollection) for an index after it is constructed by using any of the following methods:
58-
59-
* `myIndex.FieldDefinitionCollection.TryAdd`
60-
* `myIndex.FieldDefinitionCollection.AddOrUpdate`
61-
* `myIndex.FieldDefinitionCollection.GetOrAdd`
62-
63-
These modifications __must__ be done before any indexing or searching is executed.
64-
65-
### Add a field value type after construction
66-
67-
It is possible to add custom field value types after the construction of the index, but this must be done before the index is used. Some people may prefer this method of adding custom field value types. Generally, these should be modified directly after the construction of the index.
57+
The same options can be set inline when the index is registered, without a separate
58+
[`IConfigureNamedOptions`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.options.iconfigurenamedoptions-1)
59+
implementation:
6860

6961
```cs
70-
// Create the index with all of the defaults
71-
var myIndex = new LuceneIndex(
72-
"MyIndex",
73-
new SimpleFSDirectory(new DirectoryInfo("C:\\TestIndexes")));
74-
75-
// Add a custom field value type
76-
myIndex.FieldValueTypeCollection.ValueTypeFactories
77-
.TryAdd(
78-
"phonenumber",
79-
name => new GenericAnalyzerFieldValueType(
80-
name,
81-
new PhoneNumberAnalyzer()));
82-
83-
// Map a field to use the custom field value type
84-
myIndex.FieldDefinitionCollection.TryAdd(
85-
new FieldDefinition("Phone", "phonenumber"));
62+
services.AddExamineLuceneIndex("MyIndex", options =>
63+
{
64+
options.FieldDefinitions = new FieldDefinitionCollection(
65+
new FieldDefinition("Price", FieldDefinitionTypes.Double));
66+
});
8667
```
8768

69+
An index's field definitions are fixed once the index is in use. [`IIndex.FieldDefinitions`](xref:Examine.IIndex#Examine_IIndex_FieldDefinitions) exposes them as a [`ReadOnlyFieldDefinitionCollection`](xref:Examine.ReadOnlyFieldDefinitionCollection) for inspection only - all configuration __must__ be done through the options above, before any indexing or searching is executed.
70+
8871
## Value types
8972

9073
Value types are responsible for:
@@ -163,7 +146,7 @@ public sealed class ConfigureIndexOptions : IConfigureNamedOptions<LuceneDirecto
163146
public ConfigureIndexOptions(ILoggerFactory loggerFactory)
164147
=> _loggerFactory = loggerFactory;
165148

166-
public void Configure(string name, LuceneDirectoryIndexOptions options)
149+
public void Configure(string? name, LuceneDirectoryIndexOptions options)
167150
{
168151
switch (name)
169152
{
@@ -215,71 +198,88 @@ That returns an result [`ValueSetValidationResult`](xref:Examine.ValueSetValidat
215198

216199
Examine only has one implementation: [`ValueSetValidatorDelegate`](xref:Examine.Lucene.Providers.ValueSetValidatorDelegate) which can be used by developers as a simple way to create a validator based on a callback, else developers can implement this interface if required. By default, no ValueSet validation is done with Examine.
217200

201+
## Index behavior options
202+
203+
[`LuceneIndexOptions`](xref:Examine.Lucene.LuceneIndexOptions) also controls how the underlying Lucene index reader and writer behave. These are set the same way as any other option.
204+
205+
* __NrtEnabled__ _`bool`_ - Whether Near Real-Time (NRT) searching is enabled. Default `true`. With NRT enabled, searchers see indexed documents without waiting for a commit.
206+
* __NrtTargetMinStaleSec__ _`double`_ - The lower staleness bound for NRT reopens, in seconds. Default `1.0`.
207+
* __NrtTargetMaxStaleSec__ _`double`_ - The upper staleness bound for NRT reopens, in seconds. Default `60.0`.
208+
* __NrtCacheMaxMergeSizeMB__ _`double`_ - Maximum merge size in megabytes held in the NRT cache. Default `5.0`.
209+
* __NrtCacheMaxCachedMB__ _`double`_ - Maximum total megabytes held in the NRT cache. Default `60.0`.
210+
* __IndexDeletionPolicy__ _`IndexDeletionPolicy`_ - The Lucene index deletion policy. Required when [replicating](xref:replication) an index.
211+
* __UnlockIndex__ _`bool`_ - On [`LuceneDirectoryIndexOptions`](xref:Examine.Lucene.LuceneDirectoryIndexOptions). If `true`, forcibly unlocks the index directory on startup.
212+
* __DirectoryFactory__ _[`IDirectoryFactory`](xref:Examine.Lucene.Directories.IDirectoryFactory)_ - On [`LuceneDirectoryIndexOptions`](xref:Examine.Lucene.LuceneDirectoryIndexOptions). Determines the Lucene `Directory` backing the index.
213+
214+
```cs
215+
services.AddExamineLuceneIndex("MyIndex", options =>
216+
{
217+
// Reopen the searcher more aggressively than the default
218+
options.NrtTargetMinStaleSec = 0.5;
219+
options.NrtTargetMaxStaleSec = 10.0;
220+
});
221+
```
222+
223+
Lowering the staleness targets makes newly indexed documents searchable sooner at the cost of more frequent reader reopens.
224+
218225
## Facets configuration
219226

220227
When using the facets feature it's possible to add facets configuration to change the behavior of the indexing.
221228

222229
For example, you can allow multiple values in an indexed field with the configuration below.
223230
```csharp
224-
// Create a config
225-
var facetsConfig = new FacetsConfig();
226-
227-
// Set field to be able to contain multiple values (This is default for a field in Examine. But you only need this if you are actually using multiple values for a single field)
228-
facetsConfig.SetMultiValued("MultiIdField", true);
229-
230-
services.AddExamineLuceneIndex("MyIndex",
231+
services.AddExamineLuceneIndex("MyIndex", options =>
232+
{
231233
// Set the indexing of your fields to use the facet type
232-
fieldDefinitions: new FieldDefinitionCollection(
234+
options.FieldDefinitions = new FieldDefinitionCollection(
233235
new FieldDefinition("Timestamp", FieldDefinitionTypes.FacetDateTime),
236+
new FieldDefinition("MultiIdField", FieldDefinitionTypes.FacetFullText));
234237

235-
new FieldDefinition("MultiIdField", FieldDefinitionTypes.FacetFullText)
236-
),
237-
// Pass your config
238-
facetsConfig: facetsConfig
239-
);
238+
// Set field to be able to contain multiple values. (This is default for a field in Examine,
239+
// so you only need this if you are actually using multiple values for a single field.)
240+
options.FacetsConfig.SetMultiValued("MultiIdField", true);
241+
});
240242
```
241243

242244
Without this configuration for multiple values, you'll notice that your faceted search breaks or behaves differently than expected.
243245

244246
### Hierarchical and Taxonomy Facets configuration
245247

246-
To enable support for hierarchical facets as well as supporting faster faceting the Taxonomy Facet sidecar index can be enabled.
248+
To enable support for hierarchical facets as well as supporting faster faceting the Taxonomy Facet sidecar index can be used.
249+
250+
[`LuceneIndexOptions.UseTaxonomyIndex`](xref:Examine.Lucene.LuceneIndexOptions#Examine_Lucene_LuceneIndexOptions_UseTaxonomyIndex) is __`true` by default__. Setting it to `false` switches faceting over to `SortedSetDocValues` and no sidecar index is written.
247251

248-
1. Set LuceneIndexOptions.UseTaxonomyIndex = true; for the index. This enables the use of the Taxonomy sidecar index.
249-
2. Change the Field Definitions to use the "FacetTaxonomy" Field Definition Types instead of the "Facet" types. E.g. FieldDefinitionTypes.FacetFullText => FieldDefinitionTypes.FacetTaxonomyFullText.
250-
3. To enable hierarchical facets on a field, call FacetsConfig.SetHierarchical("facetfieldname", true);
252+
1. Leave `LuceneIndexOptions.UseTaxonomyIndex` as `true` for the index (or set it explicitly).
253+
2. Change the Field Definitions to use the "FacetTaxonomy" Field Definition Types instead of the "Facet" types. E.g. `FieldDefinitionTypes.FacetFullText` => `FieldDefinitionTypes.FacetTaxonomyFullText`.
254+
3. To enable hierarchical facets on a field, call `FacetsConfig.SetHierarchical("facetfieldname", true)`.
251255

252256
Example:
253257

254258
```csharp
255-
// Create a config
256-
var facetsConfig = new FacetsConfig();
257-
258-
// Set field to be able to support hierarchical facets
259-
facetsConfig.SetHierarchical("hierarchyFacetfield", true);
260-
261-
// Set field to be able to contain multiple values (This is default for a field in Examine. But you only need this if you are actually using multiple values for a single field)
262-
facetsConfig.SetMultiValued("MultiIdField", true);
263-
264-
services.AddExamineLuceneIndex("MyIndex",
259+
services.AddExamineLuceneIndex("MyIndex", options =>
260+
{
265261
// Set the indexing of your fields to use the facet Taxonomy type
266-
fieldDefinitions: new FieldDefinitionCollection(
262+
options.FieldDefinitions = new FieldDefinitionCollection(
267263
new FieldDefinition("Timestamp", FieldDefinitionTypes.FacetTaxonomyDateTime),
268264
new FieldDefinition("hierarchyFacetfield", FieldDefinitionTypes.FacetTaxonomyFullText),
265+
new FieldDefinition("MultiIdField", FieldDefinitionTypes.FacetTaxonomyFullText));
266+
267+
// Use the Taxonomy sidecar index (this is the default)
268+
options.UseTaxonomyIndex = true;
269+
270+
// Set field to be able to support hierarchical facets
271+
options.FacetsConfig.SetHierarchical("hierarchyFacetfield", true);
269272

270-
new FieldDefinition("MultiIdField", FieldDefinitionTypes.FacetTaxonomyFullText)
271-
),
272-
// Pass your config
273-
facetsConfig: facetsConfig,
274-
// Enable the Taxonomy sidecar index
275-
useTaxonomyIndex: true
276-
);
273+
// Set field to be able to contain multiple values. (This is default for a field in Examine,
274+
// so you only need this if you are actually using multiple values for a single field.)
275+
options.FacetsConfig.SetMultiValued("MultiIdField", true);
276+
});
277277
```
278278

279279
**Note: See more examples of how facets configuration can be used under [Searching](xref:searching)**
280280

281281
To explore other configuration settings see the links below:
282-
- [FacetsConfig API docs](https://lucenenet.apache.org/docs/4.8.0-beta00016/api/facet/Lucene.Net.Facet.FacetsConfig.html#methods)
282+
- [FacetsConfig API docs](https://lucenenet.apache.org/docs/4.8.0-beta00018/api/facet/Lucene.Net.Facet.FacetsConfig.html#methods)
283283
- [Facets with lucene](https://norconex.com/facets-with-lucene/). See how the config is used in the code examples.
284284

285285
## Luke

docs/articles/indexing.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,9 @@ private void IndexingError(object sender, IndexingErrorEventArgs e)
208208

209209
#### [LuceneIndex.DocumentWriting](xref:Examine.Lucene.Providers.LuceneIndex#Examine_Lucene_Providers_LuceneIndex_DocumentWriting)
210210

211-
If using Examine with the default Lucene implementation then the [`IIndex`](xref:Examine.IIndex) implementation will be [`LuceneIndex`](xref:Examine.Lucene.Providers.LuceneIndex). This event provides access to the Lucene [`Document`](https://lucenenet.apache.org/docs/4.8.0-beta00016/api/core/Lucene.Net.Documents.Document.html) object before it gets added to the Lucene Index.
211+
If using Examine with the default Lucene implementation then the [`IIndex`](xref:Examine.IIndex) implementation will be [`LuceneIndex`](xref:Examine.Lucene.Providers.LuceneIndex). This event provides access to the Lucene [`Document`](https://lucenenet.apache.org/docs/4.8.0-beta00018/api/core/Lucene.Net.Documents.Document.html) object before it gets added to the Lucene Index.
212212
213-
You can use this event to entirely customize how the data is stored in the Lucene index, including adding custom boosting profiles, changing the [`Document`](https://lucenenet.apache.org/docs/4.8.0-beta00016/api/core/Lucene.Net.Documents.Document.html)'s field values or types, etc...
213+
You can use this event to entirely customize how the data is stored in the Lucene index, including adding custom boosting profiles, changing the [`Document`](https://lucenenet.apache.org/docs/4.8.0-beta00018/api/core/Lucene.Net.Documents.Document.html)'s field values or types, etc...
214214
215215
Example of how to listen the event:
216216

0 commit comments

Comments
 (0)