This is the 28th day of my participation in the August Challenge
Introduction to the
What is a MeiliSearch?
MeiliSearch is an open source search engine implemented by Rust. It is similar to ElasticSearch in many functions. It can also store logs and search data, but it is not as convenient and powerful as ElasticSearch
The characteristics of
- Search is experience (return result < 50 ms)
- The full text retrieval
- Tolerance (understanding of typos and misspellings)
- Search and filter
- Support for Chinese characters (Chinese characters)
- Support synonyms
- Easy to install, deploy, and maintain
- Support to return the entire document
- Highly customizable
- RESTful API
Portal: docs.meilisearch.com/
The installation
Use the official recommended docker one-click installation, if you just want to do experiments, do not persist data, you can delete -v and other parameters
The service starts up in about 10 seconds, making it fast to start and easy to deploy
docker run -p 7700:7700 -v "$(pwd)/data.ms:/data.ms" getmeili/meilisearch
Copy the code
Download sample data:
Download from github.com/meilisearch…
Import sample data
curl -i -X POST 'http://127.0.0.1:7700/indexes/movies/documents' \
--header 'content-type: application/json' \
--data-binary @movies.json
Copy the code
UI
After completing the preceding steps, open http://ip:7700 to access the MeiliSearch UI. The UI is enabled by default. You are advised to disable the UI in the production environment to avoid data security problems
Below is a demonstration of search GIF images, you can see the search is very fast – images from the official website
use
Elasticsearch supports HTTP as well as various SDKS
The curl way
Directly use the curl command request address + path parameters, you can return data, pipe | jq is behind the json formatting tool under Linux, prior to install
curl 'http://127.0.0.1:7700/indexes/movies/search? q=botman+robin&limit=2' | jq
Copy the code
A web interface
There is also an open source Web project for interactive testing and using MeiliSearch(pure JS, not vUE based ✨)
Portal: github.com/meilisearch…
While there are tools to use directly, you still need to write code to integrate into your business. Here are some examples based on the Go SDK
API example
The MeiliSearch API can be divided into five major categories
- The index operation
- The document operation
- Search operations
- Set up management
- System management
The document operation includes index operation, which will be automatically created if the index does not exist in the operation document
The system and Settings classes belong to the configuration item management and operations section of the index
Initialize the
Simplify code redundancy later by making the client global
Since the apikey was not set when starting the service, there is no time to set it, for example: export MEILI_MASTER_KEY= XXX
var (
client *meilisearch.Client
err error
)
func init() {
client = meilisearch.NewClient(meilisearch.ClientConfig{
Host: "http://ip:7700".APIKey: "".Timeout: 0})},Copy the code
The index operation
Indexing operations, apis directly provide semantic methods. Call execution, including create, view, and delete
func indexOperation() {
idx: ="fruits"
// Create index
index, _ := client.CreateIndex(&meilisearch.IndexConfig{
Uid: idx,
PrimaryKey: idx + "_id",
})
fmt.Println(index.UID)
// Get the index
index2, _ := client.GetIndex(idx)
fmt.Println(index2)
// Drop index
ok, _ := client.DeleteIndex(idx)
fmt.Println(ok)
// List all indexes
indexes, _ := client.GetAllIndexes()
fmt.Println(indexes)
}
Copy the code
The document operation
Using curl, you can import a batch of official data provided by curl
Of note are the operations to add and update documents.
- Add documents:
If the index does not exist, it is created automatically. If the document does not exist, a new document will be created, if the document does exist, the entire document will be overwritten, and fields in the previous document that were not in the new document will be deleted
- Update the document
If the index does not exist, it is created automatically. This update will only update parts of the old document, and fields that do not exist in the new document will remain
func documentsOperation() {
indexName: ="movies"
// Get a document
var a interface{}
client.Index(indexName).GetDocument("25684", &a)
fmt.Println(a)
// Get all documents
var b interface{}
request := meilisearch.DocumentsRequest{Limit:2}
client.Index(indexName).GetDocuments(&request,&b)
fmt.Println(b)
// Add documents
documents := []map[string]interface{}{
{
"id": 287949."title": "Shazam"."poster": "https://image.tmdb.org/t/p/w1280/xnopI5Xtky18MPhK40cZAGAOVeV.jpg"."overview": "A boy is given the ability to become an adult superhero in times of need with a single magic word."."release_date": "2019-03-23",
},
}
addDocuments, _ := client.Index(indexName).AddDocuments(documents)
fmt.Println(addDocuments.UpdateID)
// Update the document
documents2 := []map[string]interface{}{
{
"id": 287947."title": "Shazam ⚡ ️"."genres": "comedy",
},
}
updateDocuments2, _ := client.Index(indexName).UpdateDocuments(documents2)
fmt.Println(updateDocuments2.UpdateID)
// Delete a document
document._ := client.Index(indexName).DeleteDocument("25684")
fmt.Println(document.UpdateID)
// Batch delete
client.Index("movies").DeleteDocuments([]string{"23488"."153738"."437035"."363869",})
// Delete all documents
client.Index("movies").DeleteAllDocuments()
}
Copy the code
Search operations
Once the data is written in, most of the operation is looking up the data, and the Search API is just Search
Search receives data from a SearchRequest structure that supports 10 criteria (filter, highlight, limit, length, skip, and so on)
func searchOperation() {
// Limit returns to 10
request := &meilisearch.SearchRequest{
Limit: 10,
}
search, err := client.Index("movies").Search("Harry Potter", request)
iferr ! = nil { log.Println(Query error:,err)
}
fmt.Println(search.Hits)
// highlight
// Filter those with book_id greater than 10
request2 := &meilisearch.SearchRequest{
AttributesToHighlight: []string{"*"},
Filters: "book_id > 10",
}
search2, _ := client.Index("movies").Search("prince", request2)
fmt.Println(search2.Hits)
}
Copy the code
Set up management
Settings management is a configuration item for an index, either for a single index or for all indexes globally
The configuration items are synonyms, stop terms, ranking rules, Filtering properties, unique properties, search properties, and display properties
The following example demonstrates how to view, set, and reset configuration items
func settingsManager() {
// View all index configuration items
settings, _ := client.Index("movies").GetSettings()
fmt.Printf("%#v",settings)
// Update all index configuration items
distinctAttribute: ="movies"
settingsData := meilisearch.Settings{
RankingRules: []string{
"words"."typo"."proximity"."attribute"."exactness"."desc(release_date)"."desc(rank)",},DistinctAttribute: &distinctAttribute,
SearchableAttributes: []string{
"title"."description"."genre",},DisplayedAttributes: []string{
"title"."description"."genre"."release_date",},StopWords: []string{
"the"."a"."an",},Synonyms: map[string][]string{
"wolverine": []string{"xmen"."logan"},
"logan": []string{"wolverine"},
},
}
updateSettings, _ := client.Index("movies").UpdateSettings(&settingsData)
fmt.Println(updateSettings.UpdateID)
// Reset all index configuration items
resetSettings, _ := client.Index("movies").ResetSettings()
fmt.Println(resetSettings)
// View index stop terms
words, _ := client.Index("movies").GetStopWords()
fmt.Println(words)
// Update index stop terms
stopWords := []string{"of"."the"."to"}
updateStopWords, _ := client.Index("movies").UpdateStopWords(&stopWords)
fmt.Println(updateStopWords.UpdateID)
// Resets the index stop term
resetStopWords, _ := client.Index("movies").ResetStopWords()
fmt.Println(resetStopWords.UpdateID)
// View index ranking rules
rules, _ := client.Index("movies").GetRankingRules()
fmt.Println(rules)
// Update index ranking rules
rankingRules := []string{
"words"."typo"."proximity"."attribute"."exactness"."asc(release_date)"."desc(rank)",
}
updateRankingRules, _ := client.Index("movies").UpdateRankingRules(&rankingRules)
fmt.Println(updateRankingRules.UpdateID)
// Reset index ranking rules
resetRankingRules, _ := client.Index("movies").ResetRankingRules()
fmt.Println(resetRankingRules.UpdateID)
// The filter attribute is not implemented yet
// View index unique properties
attribute, _ := client.Index("movies").GetDistinctAttribute()
fmt.Println(attribute)
// Update index unique attributes
updateDistinctAttribute, _ := client.Index("movies").UpdateDistinctAttribute("movie_id")
fmt.Println(updateDistinctAttribute.UpdateID)
// Resets index unique attributes
resetDistinctAttribute, _ := client.Index("movies").ResetDistinctAttribute()
fmt.Println(resetDistinctAttribute.UpdateID)
// View index search properties
attributes, _ := client.Index("movies").GetSearchableAttributes()
fmt.Println(attributes)
// Update index search attributes
searchableAttributes := []string{
"title"."description"."genre",
}
updateSearchableAttributes, _ := client.Index("movies").UpdateSearchableAttributes(&searchableAttributes)
fmt.Println(updateSearchableAttributes.UpdateID)
// Resets the index search attribute
resetSearchableAttributes, _ := client.Index("movies").ResetSearchableAttributes()
fmt.Println(resetSearchableAttributes.UpdateID)
// View index display properties
displayedAttributes, _ := client.Index("movies").GetDisplayedAttributes()
fmt.Println(displayedAttributes)
// Update index display properties
displayedAttributesData := []string{
"title"."description"."genre"."release_date",
}
updateDisplayedAttributes, _ := client.Index("movies").UpdateDisplayedAttributes(&displayedAttributesData)
fmt.Println(updateDisplayedAttributes.UpdateID)
// Resets the index display attribute
resetDisplayedAttributes, _ := client.Index("movies").ResetDisplayedAttributes()
fmt.Println(resetDisplayedAttributes.UpdateID)
}
Copy the code
System management
This part of THE API is mainly about operation and maintenance related issues, task status, health detection, data backup, etc
func systemManager() {
// Get the update status
status, _ := client.Index("movies").GetUpdateStatus(1)
fmt.Println(status)
// Get all updates
updateStatus, _ := client.Index("movies").GetAllUpdateStatus()
fmt.Println(updateStatus)
// Get index statistics
stats, _ := client.Index("movies").GetStats()
fmt.Println(stats)
// Get statistics for all indexes
allStats, _ := client.GetAllStats()
fmt.Println(allStats)
// Check the instance health
health, _ := client.Health()
fmt.Println(health.Status)
// Depending on the instance version information
version, _ := client.GetVersion()
fmt.Println(version.BuildDate,version.PkgVersion)
// Create a backup
respDump, _ := client.CreateDump()
fmt.Println(respDump.Status)
// Check the backup status
respDumpStatus, _ := client.GetDumpStatus(respDump.UID)
fmt.Println(respDumpStatus)
}
Copy the code
conclusion
After testing MeiliSearch, it does achieve the characteristics of fast deployment, fast startup and fast search in small business search (without large business environment), which provides another choice in search scenarios
API convenient semantics is very good, easy to use simple, the execution of the action corresponding to a method, very care of the small white
Feeling can be integrated into the management background search, small program search, blog search, internal resource search and other scenarios
Of course, thousands of words are not as good as their actual use, feel, the next generation of search engine MeiliSearch