Elasticsearch .NET only allows me to bulk upload 80 times - elasticsearch

I am using Elasticsearch.NET (5.6) on ASP.NET API (.NET 4.6) on Windows, and try to publish to elasticsearch hosted on AWS (I have tried both 5.1.1 and 6, both same behaviour).
I have the following code which bulk index the documents to Elasticsearch. Image calling the below code block many times:
var node = new System.Uri(restEndPoint);
var settings = new ConnectionSettings(node);
var lowlevelClient = new ElasticLowLevelClient(settings);
var index = indexStart + indexSuffix;
var items = new List<object>(list.Count() * 2);
foreach (var conn in list)
{
items.Add(new { index = new { _index = index, _type = "doc", _id = getId(conn) } });
items.Add(conn);
}
try
{
var indexResponse = lowlevelClient.Bulk<Stream>(items);
if (indexResponse.HttpStatusCode != 200)
{
throw new Exception(indexResponse.DebugInformation);
}
return indexResponse.HttpStatusCode;
}
catch (Exception ex)
{
ExceptionManager.LogException(ex, "Cannot publish to ES");
return null;
}
It runs fine, can publish documents to Elasticsearch, but it only can run 80 times, after 80 times, it will always get exception:
# OriginalException: System.Net.WebException: The operation has timed out
at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
at System.Net.HttpWebRequest.GetRequestStream()
at Elasticsearch.Net.HttpConnection.Request[TReturn](RequestData requestData) in C:\Users\russ\source\elasticsearch-net-5.x\src\Elasticsearch.Net\Connection\HttpConnection.cs:line 148
The most interesting part is that: I have tried to change the bulk size to be 200 or 30, and it turned out to be 16000 and 2400, meaning both ends up at 80 times. (Each document size is very similar)
Any ideas? Thanks

There is a connection limit (Also refer to comments from #RussCam under the question). So the real issue is that the Stream in the response holding the connections.
So the fix is either indexResponse.Body.Dispose (I haven't tried this one) or use VoidResponse: reportClient.BulkAsync<VoidResponse>(items); which does not require the response stream. I've tried the second and it works.

Related

Issue with Painless Script Elasticsearch Watcher

I am creating a watcher in elasticsearch that reports when we havent had new entry or events in the index for 10 minutes this is further split out by looking at the source field in the entry.
I am only getting the last 10 mins of the index and seeing which source is not present in the buckets.
to do this I am first creating a list of all the source types we receive then creating a list from the bucket keys returned. Then I want to compare the lists to see which one is missing to then pass this into the message.
I am getting a generic error for the for loop. Any feedback is helpful quite new to elastic and painless so could be something simple I've missed.
"transform": {
"script": {
"source": """String vMessage = 'Clickstream data has been loaded although there are no iovation records from the following source in the last 10 mins:
';if(ctx.payload.clickstream.hits.total > 0 && ctx.payload.iovation.aggregations.source.buckets.size() < 3) { source_list = ['wintech', 'login', 'clickstream']; source_array = new String[] for (source in ctx.payload.iovation.aggregations.source.buckets){ source_array.add(source.key); } for (key in source_list){ if (!source_array.contains(key){ vMessage += '<ul><li>' + key + '</li></ul>';} } }return [ 'message': vMessage ];""",
"lang": "painless"
}
},
So I figured it out after digging through more documentation.
I was declaring my lists incorrectly. To declare a list it needs to be in format as below.
List new_list = new ArrayList();
This solved my issue and now the transform script works as expected.
"""String vMessage = 'Clickstream data has been loaded although there are no iovation records from the following source in the last 10 mins:
';if(ctx.payload.clickstream.hits.total > 0 && ctx.payload.iovation.aggregations.source.buckets.size() < 3) { List source_list = new ArrayList(['wintech', 'login', 'clickstream']); List source_array = new ArrayList(); for (source in ctx.payload.iovation.aggregations.source.buckets){ source_array.add(source.key); } for (key in source_list){ if (!source_array.contains(key)){ vMessage += '<ul><li>' + key + '</li></ul>';} } }return [ 'message': vMessage ];""",

Chat app list last messages of each peer using parse server

I am doing a chat app using parse server, everything is great but i tried make to list just last message for every remote peer. i didn't find any query limitation how to get just one message from every remote peer how can i make this ?
Query limitation with Parse SDK
To limit the number of object that you get from a query you use limit
Here is a little example:
const Messages = Parse.Object.extend("Messages");
const query = new Parse.Query(Messages);
query.descending("createdAt");
query.limit(1); // Get only one result
Get the first object of a query with Parse SDK
In you case as you really want only one result you can use Query.first.
Like Query.find the method Query.first make a query and will return only the first result of the Query
Here is an example:
const Messages = Parse.Object.extend("Messages");
const query = new Parse.Query(Messages);
query.descending("createdAt");
const message = await query.first();
I hope my answer help you 😊
If you want to do this using a single query, you will have to use aggregate:
https://docs.parseplatform.org/js/guide/#aggregate
Try something like this:
var query = new Parse.Query("Messages");
var pipeline = [
{ match: { local: '_User$' + userID } },
{ sort: { createdAt: 1 } },
{ group: { remote: '$remote', lastMessage: { $last: '$body' } } },
];
query.aggregate(pipeline)
.then(function(results) {
// results contains unique score values
})
.catch(function(error) {
// There was an error.
});

Get full JSON response from Sonarqube Web API

I am using Sonarqube web API to detect bugs in spoon. But I'm not getting the full list of about 189 bugs, but only about 100 even when I used types=BUG parameter. The GET request I'm using is https://sonarqube.ow2.org/api/issues/search?componentKeys=fr.inria.gforge.spoon:spoon-core&types=BUG . Is there any way to get the full JSON response?
You get only 100 items as 100 is the default pagesize for Web api pagination.
In your example when using:
https://sonarqube.ow2.org/api/issues/search?componentKeys=fr.inria.gforge.spoon:spoon-core&types=BUG&ps=200
you'll get all 189 bugs. The max value for pagesize is 500.
If you want to know the total count for issues you'll need to check the response:
{
"paging": {
"pageIndex": 1,
"pageSize": 100,
"total": 189 <<---------------------------
},
"issues": [
{
...
A groovy snippet using total to get all issues with looping:
import groovy.json.*
def sonarRest(url,method) {
jsonSlurper = new JsonSlurper()
raw = '...:'
bauth = 'Basic ' + javax.xml.bind.DatatypeConverter.printBase64Binary(raw.getBytes())
conn = new URL(url).openConnection() as HttpURLConnection
conn.setRequestMethod(method)
conn.setRequestProperty("Authorization", bauth)
conn.connect()
httpstatus = conn.responseCode
object = jsonSlurper.parse(conn.content)
}
issues = sonarRest('https://sonarhost/api/issues/search?severities=INFO&ps=1', 'GET')
total = (issues.total.toFloat()/100).round()
counter = 1
while(counter <= total)
{
issues = sonarRest("https://sonarhost/api/issues/search?severities=INFO&ps=100&p=$counter", 'GET')
println issues
counter++
}
Sorry I don't even need it. I can add rule to the parameter since I'm only using one rule at a time.

Elasticsearch (NEST client) - How to search across multiple indices using OIS

I need to search across multiple indices using OIS(Object Initializer Syntax).
I have seen examples of executing search across multiple indices with Fluent DSL, but I still do not know how to execute an equivalent search with OIS.
Here is my OIS search(Only searching against one index) :
var searchResult =
await _client.LowLevel.SearchAsync<string>(ApplicationsIndexName, "application", new SearchRequest()
{
From = (query.PageSize * query.PageNumber) - query.PageSize,
Size = query.PageSize,
Query = GetQuery(query),
Aggregations = GetAggregations()
});
Which modifications can be done, so I can search across multiple indices?
After some research, I found out how to search across multiple indices:
var searchResult =
await _client.LowLevel.SearchAsync<string>(new SearchRequest()
{
IndicesBoost = new Dictionary<IndexName, double>
{
{ "applications", 1.4 },
{ "attachments", 1.4 }
},
From = (query.PageSize * query.PageNumber) - query.PageSize,
Size = query.PageSize,
Query = GetQuery(query),
Aggregations = GetAggregations()
});

SolrNet Error - Unable to read data from the transport connection: The connection was closed

I'm trying to search a Solr server from a webservice using SolrNet. I set up the connection in the global.asax: Startup.Init<ApartmentDoc>("http://192.168.0.100:8080/solr/");
I'm trying to query the server in a class file via:
var solr = ServiceLocator.Current.GetInstance<ISolrOperations<ApartmentDoc>>();
var apartments = solr.Query(SolrQuery.All, new QueryOptions
{
ExtraParams = new Dictionary<string, string> {
{ "defType", "edismax" } ,
{ "fl", "*,score,_dist_:geodist() " } ,
{ "bf", "recip(geodist(),1,1000,1000)" } ,
{ "fq", string.Format("{{!geofilt d={0}}}", radius * 1.609344) } ,
{ "sfield", "Location" } ,
{ "pt", string.Format("{0},{1}", centerLat, centerLong) }
}
});
return apartments;
The error I'm getting is: Unable to read data from the transport connection: The connection was closed.
I've checked the logs in TomCat, and the request is going through and the results appear to have been returned.
Any ideas why I'm not getting the results back?
Thanks,
Drew
As the 'rows' parameter wasn't defined in your code, the request is likely timing out from trying to retrieve a large number of documents. As explained in the SolrNet documentation, always define pagination parameters.

Resources