nest : how do an index mapping by passing a raw request? - elasticsearch

I would like to do an index mapping by passing through nest but by i want to give directly a raw elasticsearch request:
var setting = new ConnectionSettings(new Uri("uri"));
setting.DefaultIndex(_esIndexName);
var client = new ElasticClient(setting);
string rawEsRequest= "PUT /myindex
{
""mappings"": {
""review"": {
""properties"": {
""commentaire"": {
""analyzer"" : ""french"",
""type"": ""text"",
""fields"": {
""keyword"": {
""type"": ""keyword"",
""ignore_above"": 256
}
}
},
""date_creaation"": {
""type": "date""
}
}}}}"
//want to do this bellow
client.Mapping.rawPut(rawEsRequest);
Do you know if it is possible to give a direct elasticsearch request for doing mapping?

Yes, with the low level client in Elasticsearch.Net that is also exposed on the high level client in NEST through the .LowLevel property. You just need to remove the HTTP verb and URI as these are part of the method call on the client.
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var defaultIndex = "myindex;
var connectionSettings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex);
var client = new ElasticClient(connectionSettings);
string rawEsRequest = #"{
""mappings"": {
""review"": {
""properties"": {
""commentaire"": {
""analyzer"" : ""french"",
""type"": ""text"",
""fields"": {
""keyword"": {
""type"": ""keyword"",
""ignore_above"": 256
}
}
},
""date_creaation"": {
""type"": ""date""
}
}
}
}
}";
ElasticsearchResponse<dynamic> putResponse =
client.LowLevel.IndicesCreate<dynamic>(defaultIndex, rawEsRequest);

Related

How to config Tarantool Cartridge cluster automatically?

I have an application developed on Tarantool Cartridge. My cluster consists of 12 Tarantool instances divided through 4 replica sets (some are routers, some are storages). Now starting setup this cluster from scratch, I configure this cluster manually on Web UI admin application: create replica sets, bootstrap storages, configure failover mode.
How can I do this configuration automatically? What is the best way?
There are such tools:
Ansible role: https://github.com/tarantool/ansible-cartridge
Kubernetes operator: https://github.com/tarantool/tarantool-operator
You can start all tarantool instances that should be included in the cluster, connect to one of them via tarantoolctl and execute a script that determines the cluster topology, initialize sharding via vshard, and configure the failover mode (in the example, via etcd).
cartridge = require('cartridge')
replicasets = { {
alias = 'router1',
roles = { 'router', 'vshard-router', 'failover-coordinator' },
join_servers = { { uri = '172.20.0.2:3301' } }
}, {
alias = 'router2',
roles = { 'router', 'vshard-router', 'failover-coordinator' },
join_servers = { { uri = '172.20.0.3:3301' } }
}, {
alias = 'router3',
roles = { 'router', 'vshard-router', 'failover-coordinator' },
join_servers = { { uri = '172.20.0.4:3301' } }
}, {
alias = 'storage1',
roles = { 'storage', 'vshard-storage' },
join_servers = { { uri = '172.20.0.2:3302' },
{ uri = '172.20.0.3:3302' },
{ uri = '172.20.0.4:3302' } }
}, {
alias = 'storage2',
roles = { 'storage', 'vshard-storage' },
join_servers = { { uri = '172.20.0.3:3303' },
{ uri = '172.20.0.2:3303' },
{ uri = '172.20.0.4:3303' } }
}, {
alias = 'storage3',
roles = { 'storage', 'vshard-storage' },
join_servers = { { uri = '172.20.0.4:3304' },
{ uri = '172.20.0.2:3304' },
{ uri = '172.20.0.3:3304' } }
} }
cartridge.admin_edit_topology({ replicasets = replicasets })
cartridge.admin_bootstrap_vshard()
cartridge.failover_set_params({
mode = 'stateful',
state_provider = 'etcd2',
etcd2_params = {
prefix = '/',
lock_delay = 10,
endpoints = { '172.20.0.2:2379', '172.20.0.3:2379', '172.20.0.4:2379' }
}
})

How to stream many documents from Elasticsearch index (Scroll, Sliced Scroll)

I am looking for a way to stream all (~ 10^6+) documents via .NET Nest Client.
I want to boost performance by using parallel async requests. (e.g ActionBlock, Task.WhenAll())
old fashioned without boosting:
var objects = new List<object>();
var searchResponse = await elasticClient.SearchAsync<object>(
new SearchRequest<object>("myIndex")
{
Size = 7000,
Query = new BoolQuery
{
//...
},
// why here and in scroll itself?
Scroll = "2s",
Sort = new List<ISort>
{
//..
}
});
while (searchResponse.Documents.Any())
{
objects.AddRange(searchResponse.Documents);
searchResponse = await elasticClient.ScrollAsync<object>("2s", searchResponse.ScrollId).ConfigureAwait(false);
}
return objects;
then a try using parallel sliced scroll
var result = new ConcurrentBag<object>();
var tasks = Enumerable.Range(0, 4).Select(
id => new SearchRequest<object>("myIndex")
{
// hast to be lower than 1024?
Size = 1000,
Query = new BoolQuery
{
//...
},
// why here and in scroll itself?
Scroll = "2s",
Sort = new List<ISort>
{
//..
}
}).Select(
async searchRequest =>
{
var searchResponse = await elasticClient.SearchAsync<object>(searchRequest).ConfigureAwait(false);
while (searchResponse.Documents.Any())
{
searchResponse.Documents.Each(result.Add);
searchResponse = await elasticClient.ScrollAsync<object>("2s", searchResponse.ScrollId).ConfigureAwait(false);
}
// good idea right?
//await elasticClient.ClearScrollAsync(x => x.ScrollId(searchResponse.ScrollId)).ConfigureAwait(false);
});
await Task.WhenAll(tasks).PreserveAllExceptions().ConfigureAwait(false);
return result.ToList();
But this only gives me a fraction of the actual available documents.
More over slices scroll is limited to 1024 documents per slice.
I was not able to increase this value to 7000:
{
"myIndex_template": {
"settings": {
"index": {
"number_of_shards": "1",
"number_of_replicas": "0",
"max_slices_per_scroll": "10000"
}
}
}
}

Low level Elastic search not working properly

I am trying to do Elastic search with sort option. My query is like this:
var client = new ElasticClient(settings);
var query = new
{
query = new
{
term = new { title = "7-0 v Spurs" }
},
Sort = new List<ISort>
{
new SortField { Field = "releaseFrom", Order = SortOrder.Descending }
}
};
and my search is like this:
var stream = new MemoryStream();
client.Serializer.Serialize(query, stream);
var jsonQuery = System.Text.Encoding.UTF8.GetString(stream.ToArray());
var qRequest = new SearchRequest(jsonQuery);
var searchResponse = client.LowLevel.Search<SearchResponse<dynamic>>(IndexingService.IndexName, "article_en", qRequest);
I am getting the result, but it returns records which does not match the title and also it does not sort.
This is the query which is generated:
{ "query": { "term": { "title": "7-0 v Spurs" } }, "sort": [ { "releaseFrom": { "order": "desc" } } ] }
Anybody, with suggestion if I miss something here.
Found the solution.
Used ElasticLowLevelClient instead of ElasticClient.
Code is like this:
var lowlevelClient = new ElasticLowLevelClient(settings);
var stream = new MemoryStream();
lowlevelClient.Serializer.Serialize(query, stream);
var jsonQuery = System.Text.Encoding.UTF8.GetString(stream.ToArray());
var searchResponse = lowlevelClient.Search< SearchResponse<dynamic>>(IndexingService.IndexName, "article_en", jsonQuery);
one change in query also
match = new { title = "7-0 v Spurs" }

ElasticSearch NEST library to retrieve certain fields

Trying to achieve following,
Retrieve articles that match given id and genre
Retrieve selected fields for matching records
I have tried this with Sense(chrome plugin),
POST /d3acampaign/article/_search
{
"fields": ["title","genre"] ,
"query": {
"filtered": {
"filter": {
"bool": {
"must": [{
"term": {
"id": "6"
}
},
{
"term": {
"genre": "metal"
}
}]
}
}
}
}
}
For C# code i am trying to build the query using following construct,
FilterContainer fc = null;
TermFilter title = new TermFilter()
{
Field = "id",
Value = "6",
};
TermFilter genre = new TermFilter()
{
Field = "genre",
Value = "metal",
};
fc = title & genre;
QueryContainer qc = new FilteredQuery() { Filter = fc };
var searchRequest = new SearchRequest
{
SearchType = Elasticsearch.Net.SearchType.QueryAndFetch,
Query = qc,
Indices = new IndexNameMarker[] {"journal"},
Types = new TypeNameMarker[] { "article" },
};
var r = client.SearchAsync<Article>(searchRequest);
var l = (List<Article>) r.Result.Documents;
I am able to run this query and get matching records, but i amnt sure how to specify selected fields to retrieve. Let me know what can be changed in C# code to specify necessary fields.
Thanks in advance.
Based on this answer you can modify your request object as follow:
var searchRequest = new SearchRequest
{
...
Fields = new List<PropertyPathMarker>
{
Property.Path<Article>(p => p.YourField)
}
};
or if you will decide to use source filtering:
var searchRequest = new SearchRequest
{
...
Source = new SourceFilter
{
Include = new []
{
Property.Path<Article>(p => p.YourField)
}
}
};
Hope it helps.

Not able to get TermVector results properly in SolrNet

I'm not able to get TermVector results properly thru SolrNet. I tried with the following code.
QueryOptions options = new QueryOptions()
{
OrderBy = new[] { new SortOrder("markupId", Order.ASC) },
TermVector = new TermVectorParameters
{
Fields = new[] { "text" },
Options = TermVectorParameterOptions.All
}
};
var results = SolrMarkupCore.Query(query, options);
foreach (var docVectorResult in results.TermVectorResults)
{
foreach (var vectorResult in docVectorResult.TermVector)
System.Diagnostics.Debug.Print(vectorResult.ToString());
}
In the above code, results.TermVectorResults in the outer foreach gives the proper count whereas docVectorResult.TermVector in the inner foreach is empty.
I've copied the generated solr query of the above code and issued against solr admin and I'm properly getting the termVectors values. The actual query I issued is below
http://localhost:8983/solr/select/?sort=markupId+asc&tv.tf=true&start=0&q=markupId:%2823%29&tv.offsets=true&tv=true&tv.positions=true&tv.fl=text&version=2.2&rows=50
First you should check HTTP query to sure termvector feature is set property.
If it's not OK, change your indexing based on:
The Term Vector Component
If it is OK,You can use "ExtraParams" by changing the handler to termvector handler. Try this:
public SolrQueryExecuter<Product> instance { get; private set; }
public ICollection<TermVectorDocumentResult> resultDoc(string q)
{
string SERVER="http://localhost:7080/solr/core";//change this
var container = ServiceLocator.Current as SolrNet.Utils.Container;
instance = new SolrQueryExecuter<Product>(
container.GetInstance<ISolrAbstractResponseParser<Product>>(),
new SolrConnection(SERVER),
container.GetInstance<ISolrQuerySerializer>(),
container.GetInstance<ISolrFacetQuerySerializer>(),
container.GetInstance<ISolrMoreLikeThisHandlerQueryResultsParser<Product>>());
instance.DefaultHandler = "/tvrh";
SolrQueryResults<Product> results =
instance.Execute(new SolrQuery(q),
new QueryOptions
{
Fields = new[] { "*" },
Start = 0,
Rows = 10,
ExtraParams = new Dictionary<string, string> {
{ "tv.tf", "false" },
{ "tv.df", "false" },
{ "tv.positions", "true" },
{ "tv", "true" },
{ "tv.offsets", "false" },
{ "tv.payloads", "true" },
{ "tv.fl", "message" },// change the field name here
}
}
);
return results.TermVectorResults;
}

Resources