Hashtable mainhash = new Hashtable();
testdata td = new testdata() { value = "td" };
td.hash.Add("1", "tdvalue1");
td.hash.Add("2", "tdvalue2");
td.hash.Add("3", "tdvalue3");
td.hash.Add("4", "tdvalue4");
td.hash.Add("5", "tdvalue5");
testdata td1 = new testdata() { value = "td1" };
td1.hash.Add("1", "td1value1");
td1.hash.Add("2", "td1value2");
td1.hash.Add("3", "td1value3");
td1.hash.Add("4", "td1value4");
td1.hash.Add("5", "td1value5");
testdata td2 = new testdata() { value = "td2" };
td2.hash.Add("1", "td2value1");
td2.hash.Add("2", "td2value2");
td2.hash.Add("3", "td2value3");
td2.hash.Add("4", "td2value4");
td2.hash.Add("5", "td2value5");
testdata td3 = new testdata() { value = "td3" };
td3.hash.Add("1", "td3value1");
td3.hash.Add("2", "td3value2");
td3.hash.Add("3", "td3value3");
td3.hash.Add("4", "td3value4");
td3.hash.Add("5", "td3value5");
testdata td4 = new testdata() { value = "td4" };
td4.hash.Add("1", "td4value1");
td4.hash.Add("2", "td4value2");
td4.hash.Add("3", "td4value3");
td4.hash.Add("4", "td4value4");
td4.hash.Add("5", "td4value5");
mainhash.Add(1, td);
mainhash.Add(2, td1);
mainhash.Add(3, td2);
mainhash.Add(4, td3);
mainhash.Add(5, td4);
how to select all the keys using SelectMany by Linq into one list??
what i need to do in this??
var values = mainhash.Values.Cast<testdata>().Select(x => x.hash)
.SelectMany(x=> x.Keys);
what is wrong in this??
It doesn't know the type to use from Hashtable.Keys.
Try:
var values = mainhash.Values.Cast<testdata>().Select(x => x.hash)
.SelectMany(x => x.Keys.Cast<string>());
But better: use Dictionary<TKey,TValue> instead of Hashtable.
try below query -
var values = mainhash.Values.Cast<testdata>().SelectMany(x => x.hash.Keys.Cast<string>());
But, use dictionary instead of hashtable. It actually reduce the overhead of casting the objects.
hope above code helps you !!
Related
Does anyone know how to do multiple aggregations with nest?
I have found quite a few examples unfortunately none of them work.
Here's what I have:
Vehicles fields = new Vehicles();
//create a terms query
var query = new TermsQuery
{
IsVerbatim = true,
Field = "VehicleOwnerId",
Terms = new string[] { 25 },
};
var aggregations = new Dictionary<string, IAggregationContainer>
{
{ "years", new AggregationContainer
{
Terms = new TermsAggregation(nameof(fields.Year))
{
Field = new Field(nameof(fields.Year))
}
}
}
//,
//{ "makes", new AggregationContainer
// {
// Terms = new TermsAggregation("Make")
// {
// Field = new Field(nameof(fields.Make))
// }
// }
//}
};
//create the search request
var searchRequest = new SearchRequest
{
Query = query,
From = 0,
Size = 100,
Aggregations = aggregations
};
var result = client.SearchAsync<InventoryLiveView>(searchRequest).Result;
var years = result.Aggregations.Terms("years");
Dictionary<string, long> yearCounts = new Dictionary<string, long>();
foreach (var item in years.Buckets)
{
yearCounts.Add(item.Key, item.DocCount ?? 0);
}
If I just execute the code like this it works. Years returns the aggregates as expected. If I try to add another field (like the one commented out above) it fails and I get zero records.
How can I get multiple aggregates in one query? I see examples of it all over, but none of the examples I've tried seem to work and most seem to be outdated (including some in the Nest documentation).
I have also tried this approach which is pretty close to the documentation.
//create the search request
var searchRequest = new SearchRequest
{
Query = query,
From = 0,
Size = 100,
//Aggregations = aggregations
Aggregations = new AggregationDictionary
{
{
"childAgg", new ChildrenAggregation("childAgg", typeof(Vehicles ))
{
Aggregations = new AggregationDictionary
{
{"years", new TermsAggregation(nameof(fields.VehicleYear))},
{"makes", new TermsAggregation(nameof(fields.VehicleMakeName))},
{"models", new TermsAggregation(nameof(fields.VehicleModelName))},
}
}
}
}
};
var result = client.SearchAsync<Vehicles>(searchRequest).Result;
This just produces a null reference exception.
I guess I'll never have too worry about getting to proud as a programmer :)
It's too often that the solution to the problem makes me feel stupid when it reveals itself.
So my issue was that the field I was trying to use in the aggregation was text and couldn't be used. I switched everything to the ID fields and multiple aggregations work as expected.
So this version of the code works like a champ:
Vehicle fields = new Vehicle ();
//create a terms query
var query = new TermsQuery
{
IsVerbatim = true,
Field = "VehicleOwnerId",
Terms = new string[] { "30" },
};
string[] Fields = new[]
{
nameof(fields.Year),
nameof(fields.MakeId),
nameof(fields.ModelId)
};
var aggregations = new Dictionary<string, IAggregationContainer>();
foreach (string sField in Fields)
{
var termsAggregation = new TermsAggregation(sField)
{
Field = sField
};
aggregations.Add(sField, new AggregationContainer { Terms = termsAggregation });
}
//create the search request
var searchRequest = new SearchRequest
{
Query = query,
From = 0,
Size = 10,
Aggregations = aggregations
};
var result = client.SearchAsync<InventoryLiveView>(searchRequest).Result;
var years = result.Aggregations.Terms(nameof(fields.Year));
Dictionary<string, long> yearCounts = new Dictionary<string, long>();
foreach (var item in years.Buckets)
{
yearCounts.Add(item.Key, item.DocCount ?? 0);
}
The exact error from elasticsearch, which I saw using postman was:
Fielddata is disabled on text fields by default. Set fielddata=true on [MakeName] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.
Here is my example using SearchDescriptors. My only problem is how to serialize returned results into a proper Key Value list. Is Looping through a fields list the best way to return results.
SearchDescriptor<Advert> agghDescriptor = new SearchDescriptor<Advert>();
agghDescriptor.Aggregations(ag => ag.Terms("make", a => a.Field(f => f.Make)) &&
ag.Terms("region", a => a.Field(f => f.Region)) &&
ag.Terms("city", a => a.Field(f => f.City)) &&
ag.Terms("category", a => a.Field(f => f.Category)) &&
ag.Terms("application", a => a.Field(f => f.Application)) &&
ag.Terms("portalId", a => a.Field(f => f.PortalId)) &&
ag.Terms("isActiveAuctionAdvert", a => a.Field(f => f.IsActiveAuctionAdvert)) &&
ag.Terms("isBargainAccount", a => a.Field(f => f.IsBargainAccount)) &&
ag.Terms("condition", a => a.Field(f => f.Condition))
);
agghDescriptor.Size(0);
var json2 = _client.RequestResponseSerializer.SerializeToString(agghDescriptor);
var aggregationResult = _client.Search<Advert>(agghDescriptor);
List<string> fields = new List<string>();
fields.Add("make");
fields.Add("category");
fields.Add("region");
List<Aggregation> aggregations = new List<Aggregation>();
foreach (var field in fields)
{
var aggrs = aggregationResult.Aggregations.Terms(field);
List<AggregateItem> aggregateItems = new List<AggregateItem>();
foreach (var item in aggrs.Buckets)
{
aggregateItems.Add(new AggregateItem()
{
Count = item.DocCount ?? 0,
Key = item.Key
});
}
aggregations.Add(new Aggregation()
{
Name = field,
Aggregates = aggregateItems
});
}
I have created a Linq statement to get a list of items from the database. So I need to loop trough the query and append to object to then serialize to then be able to use as json in javascript. The problem is I cannot append to the declared object 'obj'. Can anyone help??
DataContext dataContext = new DataContext();
var query = from qr in dataContext.tblStocks
where qr.enable == true
select qr;
var obj = new JObject();
foreach (var item in query)
{
//obj = new JObject();
obj = ( new JObject(
new JProperty("stockID",item.stockID),
new JProperty("itemDepartmentID", item.itemDepartmentID),
new JProperty("item" , item.item),
new JProperty("description", item.description),
new JProperty("stockAmount", item.stockAmount),
new JProperty("priceExlVat", item.priceExlVat),
new JProperty("vat", item.vat),
new JProperty("priceIncVAT", item.priceIncVAT),
new JProperty("upc1", item.upc1),
new JProperty("upc2", item.upc2)
));
}
var serialized = JsonConvert.SerializeObject(obj);
return serialized;
You are reassigning obj each time through the loop hence all other data will be lost.
Easier to create an array:
obj = new JArray();
foreach (var item in query) {
obj.Add(new JObject(
new JProperty(...),
...));
}
Why don't you just serialize your object?
List<dynamic> obj = new List<dynamic>();
foreach(var item in query) {
obj.Add(new
{
itemDepartmentID = item.itemDepartmentID,
description = item.description,
...
});
}
var serialized = JsonConvert.SerializeObject(obj);
Alternative you could use an anonymous type in the query and just serialize the entire query for the query returns an IEnumerable<T> and this is converted automatically to an jsonArray:
DataContext dataContext = new DataContext();
var query = dataContext.tblStocks
.Where(stockItem => stockItem.enable)
.Select(stockItem => new
{
stockItem.stockID,
stockItem.itemDepartmentID,
stockItem.item,
stockItem.description,
stockItem.stockAmount,
stockItem.priceExlVat,
stockItem.vat,
stockItem.priceIncVat,
stockItem.upc1,
stockItem.upc2
});
return JsonConvert.SerializeObject(query);
I'm adding new items to a list from a IEnumerable (query.Roles).
var query = GetRoles();
var vm = new CreateUserViewModel();
vm.Role = new List<CreateUserViewModel.Item>();
foreach (var Role in query.Roles)
{
vm.Role.Add(new CreateUserViewModel.Item
{
Label = Role.Label,
RoleNumber = Role.RoleNumer
});
}
How i can do the 'Add' to the list with Linq?
AddRange should do it for you:
vm.Role.AddRange(query.Roles.Select(r => new CreateUserViewModel.Item
{
Label = r.Label,
RoleNumber = r.RoleNumer
}));
AddRange takes an IEnumerable parameter and adds each item to the collection.
vm.Role = query
.Roles
.Select(r=>new CreatUserViewModel
.Item{Label = r.Label,
RoleNumber = r.RoleNumber})
.ToList();
I am trying to convert datatable to List. Could you please help me with the query?
var result = DataTable1.AsEnumerable().Select(e => {e.Field<int>("MID"), e.Field<string>("MTX")}).ToList();
JavaScriptSerializer ser = new JavaScriptSerializer();
string json = ser.Serialize(result);
Thank you..
You need to provide names for the properties inside your Select call. These names will not automatically and unambiguously resolve in this particular case. Try
var result = DataTable1.AsEnumerable().Select(row => new { Mid = row.Field<int>("Mid"), MTX = row.Field<string>("MTX") });
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(result);
Those names will then become part of the json result. Such as
[{"Mid":1,"MTX":"A"},{"Mid":2,"MTX":"B"}]
IEnumerable<DataRow> sequence = dt.AsEnumerable();
or
List<DataRow> list = dt.AsEnumerable().ToList();
Try:
var result = DataTable1.AsEnumerable()
.Select(e => new object[] { e.Field<int>("MID"), e.Field<string>("MTX") })
.ToList();
I am curious if there is a way where I can capture the lower lines (the creation of the dictionary and loop to add values) in the linq statement itself. Right now the select new returns a new anonymous type but I am wondering if there is a way to make it return a Dictionary with all the values pre-populated.
XDocument reader = XDocument.Load("sl.config");
var configValues = from s in reader.Descendants("add") select new { Key = s.Attribute("key").Value, s.Attribute("value").Value };
Dictionary<string, string> Settings = new Dictionary<string, string>();
foreach (var s in configValues)
{
Settings.Add(s.Key, s.Value);
}
Try Enumerable.ToDictionary extension method.
XDocument reader = XDocument.Load("sl.config");
var Settings = reader.Descendants("add")
.ToDictionary(s => s.Attribute("key").Value, s => s.Attribute("value").Value);
var = XDocument.Load("sl.config").Descendants("add").ToDictionary
(x => x.Attribute("key"). Value, x => x.Attribute("value"). Value);