ElasticSearch NEST notes, elasticsearchnest
ElasticSearch NEST notes
1. What is ElasticSearch?
ElasticSearch is a powerful open source search and analytics engine that makes data easy to learn E.
It can be simply understood as a indexing and retrieval tool. Of course, it has more functions than this.
ElasticSearch consists of the server and client. The server provides REST APIs, and the client uses REST APIs.
2. How to install Elastic?
Install ElasticSearch-header pluginhttps: // github.com/mobz/elasticsearch-headDetailed descriptions are provided in this document.
Find an html
Installation Complete ~
3. How to Use the NEST client (Document: http://nest.azurewebsites.net/nest/quick-start.html)
Add IndexThe above Code does not need to be written, because when calling the following index method, ElasticSearch will directly use the defaultIndex in setting if it does not, it is automatically created.
However, if you need to use Mapping to adjust the index structure, you will need the CreateIndex method. The details will be mentioned in the Mapping below
Add data
SearchNormally, the requirement for search is generally to input a keyword (and the field name to be searched) and return a list that meets the criteria. Then, the search can be divided into full-text search and single-attribute search. As the name implies, full-text search uses keyword to match all attributes, while single-attribute search only matches the specified attributes.
Var searchResults = client. Search <T> (s => s
. Index (index)
. Query (q => q. QueryString (qs => qs. Query (keyword). DefaultOperator (Operator. And )))
);
Return searchResults. Documents;
In addition, because elasticsearch is word segmentation, when we use "One" to search for the complete word "JustOne", we must add **, this method is similar to % keyword % in SQL, but it will lead to the failure to search results when using full words, therefore, we need to use the following method (if there is a better method, please do not hesitate to inform us ):
QueryContainer query2 = new TermQuery {Field = item. Key, Value = item. Value. ToLower ()};
Term is an exact value to be indexed, that is, Foo, foo are not equal, so
When using the term query, note that the Field searched by the term query has beenIndexIt cannot be capitalized. The following is an elasticSearch-header test.
All data:
Capital search:
Lowercase search:
Use of NEST:
The following is an elasticSearch-header test:
Full term search (uppercase ):
Full term search (lower case ):
Partial search (uppercase, **):
Partial search (uppercase **):
Partial search (lower case, **):
Multi-word search: when we want to search for keyword consisting of multiple words like "t Boterhuis 2" (separated by spaces), term query cannot be queried, term query is a word query. Multi-word query is not supported
QueryString query:
As you can see, the third article is also searched, because ES parses "t Boterhuis 2" into three words "t" "Boterhuis" "2 ". Then separate the search and merge the result sets. Therefore, records with ID 4 are also searched. So how can we make the combined search?
QueryString query has a DefaultOperator attribute. We can set it to And. In this way, ES performs and operations on the search results of several terms.
However, a big problem is that if my keyword is "Aberdeen Boterhuis ",
You can also search for the result:
We found the data with ID 7 because the data firstname contains Aberdeen and the last name contains Boterhuis.
No good solutions have been found to solve this problem. If you have any good solutions, please kindly advise.
Then re-create the index
Person class:
Okay. Let's test the sorting ~
1. Sort IDS
Normal!
2. String sorting
That's strange. Where is the data going? The ID sorting is normal just now. Why is it not normal here?
Let's take a look at the breakpoint:
We can see that the status code of ConnnectionStatus is 200, indicating that the connection is successful, but we have not found any data. Next we need our header tool.
In the last tab, the header tool allows us to use json in ConnectionStatus. Request for query to verify the correctness and error. We can see that an error is reported during the query.
Can't sort on string types with more than one value per doc, or more than one token per field
Because our data is
In this case, the firstname will be parsed into multiple terms by analyze, So errors will occur during sorting.
So what should we do?
Http://blog.wiercinski.net/2011/uncategorized/elasticsearch-sorting-on-string-types-with-more-than-one-value-per-doc-or-more-than-one-token-per-field/
Here I have found some answers. We need to map a field to be sorted into two different fields, one analyzed (e.g. firstname), which is not analyzed (e.g. firtname. sort ).
In NEST, a simple method is to add an Attribute on the Attribute you want to sort.
[ElasticProperty (AddSortField = true)]
Therefore, we first Delete the original index and then re-Add the index.
Client. Map <Person> (m => m. MapFromAttributes ());
This code is very important. It mapping the object based on ElasticProperty, making firstname a multi fields, which can be seen in the red part of the Request Json.
{
"Person ":{
"Properties ":{
"Id ":{
"Type": "string"
},
"Firstname ":{
"Type": "multi_field ",
"Fields ":{
"Firstname ":{
"Type": "string"
},
"Sort ":{
"Index": "not_analyzed ",
"Type": "string"
}
}
},
"Lastname ":{
"Type": "string"
},
"Chains ":{
"Type": "string"
}
}
}
}
In addition, we can find that one person. firstname. sort is added to the header.
So now we can use this attribute for sorting.
The Code is as follows:
Var searchResults = client. Search <Person> (s => s
. Index ("zhixiao-application ")
. Sort (sort => sort. OnField (f => f. Firstname. Suffix ("sort"). Ascending ())
);
PS: Pay attention to the red code above
The sorting result is as follows:
Successful!
3. Sorting by distance
Elastic Search provides distance sorting and distance filtering. Therefore, you only need to create an index.
Now let's proceed step by step:
(1) create a model
public class Location{ public string Name { get; set; } [ElasticProperty(Type = FieldType.GeoPoint)] public Coordinate Coordinate { get; set; }}public class Coordinate{ public double Lat { get; set; } public double Lon { get; set; }}
PS: [ElasticProperty (Type = FieldType. GeoPoint)] when this attribute is for the following mapping, ES recognizes it as GeoPoint
(2) create an index and mapping
client.CreateIndex("geopoint-tests", s => s .AddMapping<Location>(f => f .MapFromAttributes() .Properties(p => p .GeoPoint(g => g.Name(n => n.Coordinate).IndexLatLon()) ) ));
The following is the request json for creating an index and mapping:
{ "settings": { "index": { } }, "mappings": { "location": { "properties": { "name": { "type": "string" }, "coordinate": { "type": "geo_point", "lat_lon": true } } } }}
(3) create data: in order to help you see the correct sorting, I set the latitude to the same, so that you can see the right and wrong sorting at a glance.
client.IndexMany(new[]{ createLocation("1", 52.310551, 5.07039), createLocation("2", 52.310551, 10.761176), createLocation("3", 52.310551, 8.07039), createLocation("4", 52.310551, 6.07039),});private static Location createLocation(string name, double latitude, double longitude){ return new Location { Name = name, Coordinate = new Coordinate { Lat = latitude, Lon = longitude } };}
(4) use of sorting:
Result:
Successful!
4. distance Filter (in fact, this should be classified in the query, but this should be modified on the Code sorted above, so it will be placed here)
The Code is as follows:
The result is as follows:
5. Update Data
Because it is relatively simple, I will not explain anything, simply go to the code
PS: Note that if you need to clear the value of an attribute and pass in null, elasticsearch considers that you do not need to update this attribute, therefore, to clear an attribute value, we need to input "".
6. delete data