I created an object and i want to search this object as an fields value. There is no problem Elasticsearch connection. also i can get all data when i use AllIndices. but i cannot get a value when search as a field. What is the problem? i follow the own Elasticsearch document.
This is My Code
var person = new Person
{
Id = 3,
Firstname = "TOM",
Lastname = "Brandly"
};
if (!client.IndexExists("person").Exists)
{
client.CreateIndex("person");
}
var indexResponse = client.Index(person);
var searchResult = client.Search<Person>(s => s
.From(0)
.Size(10)
.Query(q => q
.Term(p => p.Firstname, "TOM")));
Related
Here is a query that works in ElasticSearch.
"query":{
"match_all":{
}
},
"size":20,
"aggs":{
"CompanyName.raw":{
"terms":{
"field":"CompanyName.raw",
"size":20,
"order":{
"_count":"desc"
}
}
}
}
}
The response from ElasticSearch has a property aggregations['CompanyName.raw']['buckets'] which is an array.
I use this code to exeute the same query via NEST
string responseJson = null;
ISearchResponse<ProductPurchasing> r = Client.Search<ProductPurchasing>(rq);
using (MemoryStream ms = new MemoryStream())
{
Client.RequestResponseSerializer.Serialize<ISearchResponse<ProductPurchasing>>(r, ms);
ms.Position = 0;
using (StreamReader sr = new StreamReader(ms))
{
responseJson = sr.ReadToEnd();
}
}
However, in the resulting responseJson this array is always empty.
Where hs it gone?
How can I get it back?
Or is it that NEST doesn't support aggregates?
NEST does support aggregation, you can have a look into docs on how to handle aggregation response with NEST help.
Here you can find a short example of writing and retrieving data from simple terms aggregation:
class Program
{
public class Document
{
public int Id { get; set; }
public string Name { get; set; }
public string Brand { get; set; }
public string Category { get; set; }
public override string ToString() => $"Id: {Id} Name: {Name} Brand: {Brand} Category: {Category}";
}
static async Task Main(string[] args)
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var connectionSettings = new ConnectionSettings(pool);
connectionSettings.DefaultIndex("documents");
var client = new ElasticClient(connectionSettings);
var deleteIndexResponse = await client.Indices.DeleteAsync("documents");
var createIndexResponse = await client.Indices.CreateAsync("documents", d => d
.Map(m => m.AutoMap<Document>()));
var indexDocument = await client
.IndexDocumentAsync(new Document {Id = 1, Brand = "Tommy", Category = "men"});
var indexDocument2 = await client
.IndexDocumentAsync(new Document {Id = 2, Brand = "Diesel", Category = "men"});
var indexDocument3 = await client
.IndexDocumentAsync(new Document {Id = 3, Brand = "Boss", Category = "men"});
var refreshAsync = client.Indices.RefreshAsync();
var searchResponse = await client.SearchAsync<Document>(s => s
.Query(q => q.MatchAll())
.Aggregations(a => a
.Terms("brand", t => t
.Field(f => f.Brand.Suffix("keyword")))));
var brands = searchResponse.Aggregations.Terms("brand");
foreach (var bucket in brands.Buckets)
{
Console.WriteLine(bucket.Key);
}
}
}
Prints:
Boss
Diesel
Tommy
Hope that helps.
I want to GET all my documents by Index. I have tried the following:
var response = client.Search(s => s.Index("test").MatchAll());
the response returns "successful operation" but it hits no document despite the fact that there are many documents under that index.
To get all documents within an index, you'll want to use the Scroll API. Note that depending on how many documents we're talking about, it's likely that you'll receive them in batches through multiple HTTP requests/responses.
There's a helper in NEST for making this easier, ScrollAll()
Time processTimePerScroll = "20s";
int numberOfSlices = Environment.ProcessorCount;
var scrollAllObservable = client.ScrollAll<Person>(processTimePerScroll, numberOfSlices, sc => sc
.MaxDegreeOfParallelism(numberOfSlices)
.Search(s => s
.Query(q => q
.MatchAll()
)
)
)
var waitHandle = new ManualResetEvent(false);
Exception exception = null;
var scrollAllObserver = new ScrollAllObserver<Person>(
onNext: response =>
{
// do something with the documents
var documents = response.SearchResponse.Documents;
},
onError: e =>
{
exception = e;
waitHandle.Set();
},
onCompleted: () => waitHandle.Set()
);
scrollAllObservable.Subscribe(scrollAllObserver);
waitHandle.WaitOne();
if (exception != null)
{
throw exception;
}
I am looking for how to init a SearchRequest Object with several no nested Aggregations by using the object initializer syntax.
If the request were given as param into ElasticClient.Search() with lambda expression helper it would be written like bellow:
var response = Client.Search<person>(s => s.Aggregations(a =>
a.Terms("bucketAge", t => t.Field("age").Size(50))
.Terms("bucketCity", t => t.Field("city").Size(50))));
What is paradoxical is i found i how to write a Agg with a nested Agg
var searchRequest = new SearchRequest<person>
{
Size = 0,
Aggregations = new TermsAggregation("bucketAge")
{
Field = "age",
Size = 50,
Aggregations = new TermsAggregation("bucketcity")
{
Field = "city",
Size = 50
}
}
};
But i fail to init SearchRequest with 2 aggs on same level with Something like that:
var searchRequest = new SearchRequest<person>
{
Size = 0,
Aggregations =
{
new TermsAggregation("bucketAge")
{
Field = "age",
Size = 50
},
new TermsAggregation("bucketcity")
{
Field = "city",
Size = 50
}
}
};
How to do this please?
With the Object Initializer syntax, you can combine aggregations with &&
var searchRequest = new SearchRequest<person>
{
Size = 0,
Aggregations =
new TermsAggregation("bucketAge")
{
Field = "age",
Size = 50
} &&
new TermsAggregation("bucketcity")
{
Field = "city",
Size = 50
}
};
var searchResponse = client.Search<person>(searchRequest);
You can use the longer winded method using an aggregation dictionary if you prefer
var aggregations = new Dictionary<string, AggregationContainer>
{
{ "bucketAge", new TermsAggregation("bucketAge")
{
Field = "age",
Size = 50
}
},
{ "bucketcity", new TermsAggregation("bucketcity")
{
Field = "city",
Size = 50
}
},
};
var searchRequest = new SearchRequest<person>
{
Size = 0,
Aggregations = new AggregationDictionary(aggregations)
};
var searchResponse = client.Search<person>(searchRequest);
Note that the keys in the Dictionary<string, AggregationContainer> will be the names of the aggregations in the request.
Does the Elasticsearch NEST API expose access to /{index}/{_aliases}/*? I am trying to get a list of indexes mapped to a given alias and I cannot seem to find an appropriate method.
{
"ntdev-events017-v1": {
"aliases": {
"ntdev-events017": {}
}
}
}
http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html
You can use GetAlias method on ElasticClient.
Take a look on this example:
var indexName = "sampleindex";
var uri = new Uri("http://localhost:9200");
var settings = new ConnectionSettings(uri).SetDefaultIndex(indexName).EnableTrace();
var client = new ElasticClient(settings);
client.CreateIndex(descriptor => descriptor.Index(indexName));
var putAliasResponse = client.PutAlias(descriptor => descriptor
.Index(indexName).Name("alias1"));
var putAliasResponse2 = client.PutAlias(descriptor => descriptor
.Index(indexName).Name("alias2"));
var aliasesForIndex = client.GetAlias(descriptor => descriptor
.Index(indexName))
.Indices[indexName]
.Select(x => x.Name).ToList();
var indexesMappedToAlias = client.GetAlias(descriptor => descriptor.Alias("alias2"))
.Indices.Select(x => x.Key).ToList();
I´m having trouble populating a list with the result from an API using ReactiveOauth for wp7.
It works when i´m populating the listbox directly. But I can´t figure out how to add the object to a list instead. The list is always empty when doing it like this .Subscribe(a => lista.Add(new Device ...
Any suggestions is very appreciated.
var token = TelldusWrapper.Security.GetToken();
var lista = new List<Device>();
var client = new OAuthClient(ConsumerKey, ConsumerSecret, token)
{
Url = "http://api.telldus.com/xml/devices/list",
Parameters = { { "supportedMethods", "TELLSTICK_TURNON" } }
};
client.GetResponseText().Select(s => XElement.Parse(s))
.SelectMany(x => x.Descendants("device"))
.Select(x => new
{
Text = x.Attribute("id").Value,
Name = x.Attribute("name").Value
})
.ObserveOnDispatcher()
.Subscribe(a => listbox.Items.Add(new Device { Id = a.Text, Name = a.Name }), ex => MessageBox.Show(ex.ToString()));
//.Subscribe(a => lista.Add(new Device { Id = a.Text, Name = a.Name }), ex => MessageBox.Show(ex.ToString()));