(cherry picked from commit a1381d9146fba42cb97d72d38525fa3e721bfb03)
(cherry picked from commit 74714e02461fb47fcc0901211668e4529fac68d0)
(cherry picked from commit 7749dbfe6684498a47e3037088e7bef3542b6ce5)
(cherry picked from commit 437924971136eaed795f77edd3d3dfffa5f68103)
(cherry picked from commit a69f55bebf82a0b68bc0f66bc029eaea836cddb7)
(cherry picked from commit 24dd5fbfdbc27c887dbc24661c1005fb2e14e3c6)
(cherry picked from commit dda856d6b83936fd1c96c84544b086cbd8f63115)
(cherry picked from commit bc14f4fa97fffe82d1c666e961e313f88433cb9e)
(cherry picked from commit 78fef4f1379d8854901151d4bc62135c73db868e)
(cherry picked from commit 69e013cc515e2a50006d8d02f575ff6490d272ff)
(cherry picked from commit f173c6a2734b2dccf1424d27cd8e10fc296e44a4)
(cherry picked from commit 92f9d02547017770deafd1f715c32ae4479b8ded)
(cherry picked from commit c99d51e665370ceb71b96b3fb65184090c7e4442)
(cherry picked from commit aa0650fd2b42738a5e564c229c3eb63b8ca77f9b)
(cherry picked from commit 0a8ef91302368751df22a1967857283222bc097f)
(cherry picked from commit 7b54fe01c2ded0bbbcae6b89d9e330ca4f6ab744)
(cherry picked from commit 0e154f366f14d106d14f500f605380c29b5a3f21)
(cherry picked from commit 02d88ee16d23b9ebb04bf1af843fc5d2074783ce)
(cherry picked from commit 411924e0172a7b10de7513f2e7f60ab5341b13e4)
(cherry picked from commit f4e9ca6db59f2c5c638a0560d4ea99833d61520b)
(cherry picked from commit cd80126a23573dd5aea1e9674ee0bfa34c63ec5a)
(cherry picked from commit da626702f9743fc6e1dd77d21aff5fc3afe75912)
(cherry picked from commit 4b81d0bd046fef267bb10d2ca0cbd342c87fd4e2)
(cherry picked from commit 53ac2606694fa060879a0f4c82f6164c6f42a4d0)
(cherry picked from commit 984081f08d108acc47d312307b1c3beee3058202)
(cherry picked from commit 1c39bae3ec9b485f9969e29ed7ae8fe37b32da69)
Previously only the first term had to be matched. That default
Meilisearch behavior makes sense for e.g. some kind of autocomplete to
find and select a single result. But for filtering issues it means you
can't narrow down results by adding more terms.
This is also more consistent with other indexers and GitHub.
---
Reference:
https://www.meilisearch.com/docs/reference/api/search#matching-strategy
Fix #24662.
Replace #24822 and #25708 (although it has been merged)
## Background
In the past, Gitea supported issue searching with a keyword and
conditions in a less efficient way. It worked by searching for issues
with the keyword and obtaining limited IDs (as it is heavy to get all)
on the indexer (bleve/elasticsearch/meilisearch), and then querying with
conditions on the database to find a subset of the found IDs. This is
why the results could be incomplete.
To solve this issue, we need to store all fields that could be used as
conditions in the indexer and support both keyword and additional
conditions when searching with the indexer.
## Major changes
- Redefine `IndexerData` to include all fields that could be used as
filter conditions.
- Refactor `Search(ctx context.Context, kw string, repoIDs []int64,
limit, start int, state string)` to `Search(ctx context.Context, options
*SearchOptions)`, so it supports more conditions now.
- Change the data type stored in `issueIndexerQueue`. Use
`IndexerMetadata` instead of `IndexerData` in case the data has been
updated while it is in the queue. This also reduces the storage size of
the queue.
- Enhance searching with Bleve/Elasticsearch/Meilisearch, make them
fully support `SearchOptions`. Also, update the data versions.
- Keep most logic of database indexer, but remove
`issues.SearchIssueIDsByKeyword` in `models` to avoid confusion where is
the entry point to search issues.
- Start a Meilisearch instance to test it in unit tests.
- Add unit tests with almost full coverage to test
Bleve/Elasticsearch/Meilisearch indexer.
---------
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
A couple of notes:
* Future changes should refactor arguments into a struct
* This filtering only is supported by meilisearch right now
* Issue index number is bumped which will cause a re-index
Refactor `modules/indexer` to make it more maintainable. And it can be
easier to support more features. I'm trying to solve some of issue
searching, this is a precursor to making functional changes.
Current supported engines and the index versions:
| engines | issues | code |
| - | - | - |
| db | Just a wrapper for database queries, doesn't need version | - |
| bleve | The version of index is **2** | The version of index is **6**
|
| elasticsearch | The old index has no version, will be treated as
version **0** in this PR | The version of index is **1** |
| meilisearch | The old index has no version, will be treated as version
**0** in this PR | - |
## Changes
### Split
Splited it into mutiple packages
```text
indexer
├── internal
│ ├── bleve
│ ├── db
│ ├── elasticsearch
│ └── meilisearch
├── code
│ ├── bleve
│ ├── elasticsearch
│ └── internal
└── issues
├── bleve
├── db
├── elasticsearch
├── internal
└── meilisearch
```
- `indexer/interanal`: Internal shared package for indexer.
- `indexer/interanal/[engine]`: Internal shared package for each engine
(bleve/db/elasticsearch/meilisearch).
- `indexer/code`: Implementations for code indexer.
- `indexer/code/internal`: Internal shared package for code indexer.
- `indexer/code/[engine]`: Implementation via each engine for code
indexer.
- `indexer/issues`: Implementations for issues indexer.
### Deduplication
- Combine `Init/Ping/Close` for code indexer and issues indexer.
- ~Combine `issues.indexerHolder` and `code.wrappedIndexer` to
`internal.IndexHolder`.~ Remove it, use dummy indexer instead when the
indexer is not ready.
- Duplicate two copies of creating ES clients.
- Duplicate two copies of `indexerID()`.
### Enhancement
- [x] Support index version for elasticsearch issues indexer, the old
index without version will be treated as version 0.
- [x] Fix spell of `elastic_search/ElasticSearch`, it should be
`Elasticsearch`.
- [x] Improve versioning of ES index. We don't need `Aliases`:
- Gitea does't need aliases for "Zero Downtime" because it never delete
old indexes.
- The old code of issues indexer uses the orignal name to create issue
index, so it's tricky to convert it to an alias.
- [x] Support index version for meilisearch issues indexer, the old
index without version will be treated as version 0.
- [x] Do "ping" only when `Ping` has been called, don't ping
periodically and cache the status.
- [x] Support the context parameter whenever possible.
- [x] Fix outdated example config.
- [x] Give up the requeue logic of issues indexer: When indexing fails,
call Ping to check if it was caused by the engine being unavailable, and
only requeue the task if the engine is unavailable.
- It is fragile and tricky, could cause data losing (It did happen when
I was doing some tests for this PR). And it works for ES only.
- Just always requeue the failed task, if it caused by bad data, it's a
bug of Gitea which should be fixed.
---------
Co-authored-by: Giteabot <teabot@gitea.io>