DocumentDB LAMBDA SqlMethod.Like and .Contains NotImplemented Exception - azure-cosmosdb

Im trying to do a simple "LIKE" query using a LAMBDA expression using CreateDocumentQuery; however after trying .Contains and SqlMethod.Like and both times receiving the response NotImplementedException I don't know what to try next!

Update: As of 5/6/15, DocumentDB added a set of String functions including STARTSWITH, ENDSWITH, and CONTAINS. Please note that most of these functions do not run on the index and will force a scan.
LIKE and CONTAINS are not yet supported in DocumentDB.
You'll want to check out the DocumentDB feedback page and vote on features (e.g. LIKE and CONTAINS) to get your voice heard!

Because I only needed to search against a discreet subset of properties of the larger object I implemented a .Contains search function as below. It works as expected though I have no idea regarding performance or scalability.
Domain Models
public interface ITaxonomySearchable
{
string Name { get; set; }
string Description { get; set; }
}
public class TaxonomySearchInfo : ITaxonomySearchable {
[JsonProperty(PropertyName = "id")]
public Guid Id { get; set; }
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "description")]
public string Description { get; set; }
}
public class TaxonomyContainer : ITaxonomySearchable
{
[JsonProperty(PropertyName = "id")]
public Guid Id { get; set; }
[JsonProperty(PropertyName = "userId")]
public string UserId { get; set; }
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "description")]
public string Description { get; set; }
[JsonProperty(PropertyName = "tags")]
public string[] Tags { get; set; }
[JsonProperty(PropertyName = "taxonomy")]
public Node[] Taxonomy { get; set; }
}
Search method
public async static Task<List<TaxonomySearchInfo>> Search(string searchTerm)
{
var db = GetJsonDocumentDb.GetDb();
using (var client = GetJsonDocumentDb.GetClient())
{
var documentCollection = await GetJsonDocumentDb.GetDocumentCollection(db, client, "TaxonomyContainerCollection");
return client.CreateDocumentQuery<TaxonomySearchInfo>(documentCollection.DocumentsLink)
.AsEnumerable()
.Where(r => r.Name.Contains(searchTerm) || r.Description.Contains(searchTerm))
.ToList();
}
}

Related

Deserialize JSON into List with X++

I have a problem with generic types in X++. I need to deserialize a JSON list yet everything I tried failed. Like using IEnumerables and JsonSerializer(does it find only AX classes and can't see references library classes?).
My helper class is in a C# library and I only need to get access to values inside the response JSON that are in list. How can I archive this in X++?
//X++
defaultException defaultException= new defaultException();
defaultException= JsonConvert::DeserializeObject(response, defaultException.GetType()); <- this gives is correct yet I cant use the values in the list
//values = FormJsonSerializer::deserializeCollection(classnum(List), response, Types::Class, 'defaultException');
// C#
public class defaultException
{
public MyException exception { get; set; }
}
public class MyException
{
public string serviceCtx { get; set; }
public string serviceCode { get; set; }
public string serviceName { get; set; }
public string timestamp { get; set;}
public string referenceNumber { get; set; }
public List<exceptionDetailList> exceptionDetailList { get; set; }
}
public class exceptionDetailList
{
public int exceptionCode { get; set; }
public string exceptionDescription { get; set; }
}
Found a solution. If we have another list in this list we need to recreate the enumerator in loop again and again as needed.
defaultException defaultException = new defaultException();
defaultException = JsonConvert::DeserializeObject(batch, defaultException.GetType());
System.Collections.IEnumerable exceptionList = defaultException.exception.exceptionDetailList;
System.Collections.IEnumerator enumerator = exceptionList.GetEnumerator();
while (enumerator.MoveNext())
{
exceptionDetailList exceptionDetailList = new exceptionDetailList();
exceptionDetailList = enumerator.Current;
}

How to parse JSON child nodes as an array using json.net? [duplicate]

I am trying to make use of the API for a well known online meeting provider. One of their API calls returns an object that looks like this.
{
"5234592":{
"pollsAndSurveys":{
"questionsAsked":1,
"surveyCount":0,
"percentageSurveysCompleted":0,
"percentagePollsCompleted":100,
"pollCount":2},
"attendance":{
"averageAttendanceTimeSeconds":253,
"averageInterestRating":0,
"averageAttentiveness":0,
"registrantCount":1,
"percentageAttendance":100}
},
"5235291":{
"pollsAndSurveys":{
"questionsAsked":2,
"surveyCount":0,
"percentageSurveysCompleted":0,
"percentagePollsCompleted":0,
"pollCount":0},
"attendance":{
"averageAttendanceTimeSeconds":83,
"averageInterestRating":0,
"averageAttentiveness":0,
"registrantCount":1,
"percentageAttendance":100}
}
}
I am trying to make a strongly typed object in C# so I can deal with this data. I can create objects for the pollsAndSurveys bit and the attendance bit but I don't know how to deal with the id number, in this case 5234592 & 5235291, that is the identifier for the session.
public class AttendanceStatistics
{
[JsonProperty(PropertyName = "registrantCount")]
public int RegistrantCount { get; set; }
[JsonProperty(PropertyName = "percentageAttendance")]
public float PercentageAttendance{ get; set; }
[JsonProperty(PropertyName = "averageInterestRating")]
public float AverageInterestRating { get; set; }
[JsonProperty(PropertyName = "averageAttentiveness")]
public float AverageAttentiveness { get; set; }
[JsonProperty(PropertyName = "averageAttendanceTimeSeconds")]
public float AverageAttendanceTimeSeconds { get; set; }
}
public class PollsAndSurveysStatistics
{
[JsonProperty(PropertyName = "pollCount")]
public int PollCount { get; set; }
[JsonProperty(PropertyName = "surveyCount")]
public float SurveyCount { get; set; }
[JsonProperty(PropertyName = "questionsAsked")]
public int QuestionsAsked { get; set; }
[JsonProperty(PropertyName = "percentagePollsCompleted")]
public float PercentagePollsCompleted { get; set; }
[JsonProperty(PropertyName = "percentageSurveysCompleted")]
public float PercentageSurveysCompleted { get; set; }
}
public class SessionPerformanceStats
{
[JsonProperty(PropertyName = "attendance")]
public AttendanceStatistics Attendance { get; set; }
[JsonProperty(PropertyName = "pollsAndSurveys")]
public PollsAndSurveysStatistics PollsAndSurveys { get; set; }
}
public class WebinarPerformanceStats
{
public List<SessionPerformanceStats> Stats { get; set; }
}
I am pretty sure that the WebinarPerformanceStats is the issue but I don't know where to go from here. What would I have to change to get
NewtonSoft.Json.JsonConvert.DeserializeObject<WebinarPerformanceStats>(theJsonResponse)
to work?
Make your root object be a dictionary:
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, SessionPerformanceStats>>(theJsonResponse);
Json.NET serializes a dictionary from and to a JSON object, with the keys being converted to the property names. In your case, the ID numbers will be deserialized as the dictionary keys. If you are sure they will always be numbers, you could declare them as such:
var dictionary = JsonConvert.DeserializeObject<Dictionary<long, SessionPerformanceStats>>(theJsonResponse);
See Serialize a Dictionary and Deserialize a Dictionary

Best way to parse a Gremlin.Net response?

What is the best way to get POCO's from a Gremlin.Net response?
Right now I manually cast to dictionaries:
var results = await gremlinClient.SubmitAsync<Dictionary<string, object>>("g.V()");
var result = results[0];
var properties = (Dictionary<string, object>)result["properties"];
var value = ((Dictionary<string, object>)properties["myValue"].Single())["value"];
I found that the GremlinClient can only return dynamic objects, if you put anything else as the type, it fails (unless I was just doing something wrong).
What I ended up doing was serialising the dynamic object to JSON and then deserialising it back to the object type I wanted:
var results = await gremlinClient.SubmitAsync<dynamic>("g.V()");
JsonConvert.DeserializeObject<MyResult>(JsonConvert.SerializeObject(results));
The dynamic object is just a Dictionary, but if you serialise it first it has the proper hierarchy of fields/properties which can then be deserialised to what you actually expect.
Seems a bit of a pain to have to do the extra conversion, but only way I got it to work.
You can get your properties by using MyClass similar to
class ProviderProperties {
public object Name { get; set; }
public object contact { get; set; }
public object requesttype { get; set; }
public object address { get; set; }
public object phone { get; set; }
public object description { get; set; }
public object otherState { get; set; }
public object otherCity { get; set; }
public object addressStreet { get; set; }
}
class MyClass {
public string id { get; set; }
public string label { get; set; }
public string type { get; set; }
public ProviderProperties properties { get; set; }
}
and using it in
JsonConvert.DeserializeObject<MyClass>(JsonConvert.SerializeObject(results));
Try this approach
IGremlinClient janusClient = JanusGraphClientBuilder.BuildClientForServer(new GremlinServer("localhost", 8182)).Create();
GraphTraversalSource g = Traversal().WithRemote(new DriverRemoteConnection(janusClient));
IList<Vertex> x = g.V().HasLabel("YourLabel").Has("YourpPopertyName", "some value").ToList();

ServiceStack OrmLite CustomSelect not working?

I'm trying to use the feature documented here :
https://github.com/ServiceStack/ServiceStack.OrmLite#custom-sql-customizations
This is how I'm using it:
var q = Db.From<MemberAccess>().LeftJoin<Member>();
return Db.Select<MemberResponse>(q);
Response object:
public class MemberResponse
{
public Guid Id { get; set; }
public string MemberFirstName { get; set; }
public string MemberLastName { get; set; }
public string MemberEmail { get; set; }
[Default(OrmLiteVariables.SystemUtc)]
public string AccessedOn { get; set; }
[CustomSelect("CONCAT(LEFT(Member.FirstName, 1),LEFT(Member.LastName,1))")]
public string MemberInitial { get; set; }
}
It seems like whatever I put in CustomSelect doesn't get used. Maybe, I'm not using this correctly? Also, the Default attribute doesn't work either.I tried that as it was an example from the doco.
Any idea will be appreciated.
Thanks in advance.
The [CustomSelect] only applies to the source table. Selecting the results in a custom type is used to map the returned resultset on the MemberResponse type, it doesn't have any effect on the query that gets executed.
Likewise with [Default(OrmLiteVariables.SystemUtc)] that's used to define the default value when creating the table which is only used when it creates the Column definition, so it's only useful on the source Table Type.
Both these attributes should only be added on the source MemberAccess to have any effect, which your mapped MemberResponse can access without any attributes, e.g:
public class MemberResponse
{
public Guid Id { get; set; }
public string MemberFirstName { get; set; }
public string MemberLastName { get; set; }
public string MemberEmail { get; set; }
public string AccessedOn { get; set; }
public string MemberInitial { get; set; }
}
Sql.Custom() API
The new Sql.Custom() API added in v4.5.5 that's available on MyGet will let you select a custom SQL Fragment, e.g:
var q = Db.From<MemberAccess>().LeftJoin<Member>()
.Select<MemberAccess,Member>((a,m) => new {
Id = a.Id,
MemberFirstName = m.FirstName,
MemberLastName = m.LastName,
MemberEmail = m.Email,
MemberInitial = Sql.Custom("CONCAT(LEFT(Member.FirstName,1),LEFT(Member.LastName,1))")
});
return Db.Select<MemberResponse>(q);

Post JSON Array in Asp.Net Web API

Hi every one I am new to ASP.Net Web API and I want to Post JSON array data any get there response.
My JSON POST Array format is
{
"User_Id":"admi12n#1234","Key_Code":"3F-47-AB-84-9F-EB-D6-6B-9C-62-CC-85-98-4D-28-6B",
"ProductDetails": [
{"Product_Id":"ELT-7035","Price":"999","Quantity":"5"},
{"Product_Id":"ELT-1254","Price":"1024","Quantity":"3"}
]
}
And I want response as follows
{
"User_Id":"admi12n#1234","Key_Code":"3F-47-AB-84-9F-EB-D6-6B-9C-62-CC-85-98-4D-28-6B",
"OrderID":"Ord-021","Name":"Sabyasachi"
"ProductDetails": [
{"Product_Id":"ELT-7035","Price":"999","Quantity":"5"},
{"Product_Id":"ELT-1254","Price":"1024","Quantity":"3"}
]
}
I generate OrderID as Random and Name from posted User_Id. Here I want to post multiple product in one order.
My Order class is as follows
public class Order
{
[Key]
public long ID { get; set; }
public string Order_Id { get; set; }
public string Product_Id { get; set; }
public long Quantity { get; set; }
public long Amount { get; set; }
public string User_Id { get; set; }
public string Key_Code { get; set; }
public DateTime Order_Date { get; set; }
public DateTime Modified_Date { get; set; }
}
And my Product class as follows
public class Product
{
[Key]
public int Id { get; set; }
public string Product_Code { get; set; }
public string Product_Name { get; set; }
public string Product_Category { get; set; }
public string Product_Description { get; set; }
public string Quantity { get; set; }
public string Price { get; set; }
public string Image { get; set; }
public DateTime Created_Date { get; set; }
public DateTime Modified_Date { get; set; }
}
I am not able to ind the best way to post the order
public Order Add(Order odrerDetails) //This will not give array of data for products
{
using (var context = new EcommerceDBContext())
{
odrerDetails.Order_Id = Helper.Random(7); //Generate random orderID from my class
odrerDetails.Created_Date = DateTime.Now;
odrerDetails.Modified_Date = DateTime.Now;
//How to Save other details
context.objOrderListing.Add(odrerDetails);
context.SaveChanges();
return odrerDetails;
}
}
In API controllers my code is as follows
public HttpResponseMessage PostOrder([FromBody] Order_Listing orderData)
{
orderData = repository.Add(orderData);
var response = Request.CreateResponse<Order_Listing>(HttpStatusCode.Created, orderData);
string uri = Url.Link("DefaultApi", new { customerID = orderData.ID });
response.Headers.Location = new Uri(uri);
return response;
}
Please help me how to achieve this.
There are several issues with your code:
Your Order and Product classes do not reflect the structure of
your JSON.
The Order class contains product details in a 1:1
relationship. Based on the JSON I assume you want a 1:n relationship.
Properties in your JSON need to have the same name as
in your classes or they won't be mapped.
Change your classes to the following and it should work.
Of course you could also change the property names in your JSON.
If you can't or don't want to change your property names, consider using DTOs
public class Order
{
public string User_Id { get; set; }
public string Key_Code { get; set; }
public string OrderID { get; set; }
public string Name { get; set; }
public List<Product> ProductDetails { get; set; }
// add the rest of your properties
}
public class Product
{
public string Product_Id { get; set; }
public string Price { get; set; }
public string Prd_Qty { get; set; }
// add the rest of your properties
}
Update: added code for Add method and Api method
Your Add method would look like this:
public Order Add(Order orderWithDetails)
{
using (var context = new EcommerceDBContext())
{
orderWithDetails.Order_Id = Helper.Random(7); //Generate random orderID from my class
orderWithDetails.Created_Date = DateTime.Now;
orderWithDetails.Modified_Date = DateTime.Now;
context.objOrderListing.Add(orderWithDetails);
// Save each Product
foreach (var detail in orderWithDetails.ProductDetails)
{
//whatever you need to do in your db-context
context.objOrderDetails.Add(detail); // just an example
}
context.SaveChanges();
return orderWithDetails;
}
}
The signature of your Api method looks wrong. What is Order_Listing? This should be Order, unless it's a DTO, in wich case you need a method to get an Order from Order_Listing.
public HttpResponseMessage PostOrder([FromBody] Order orderData)
{
orderData = repository.Add(orderData);
var response = Request.CreateResponse<Order_Listing>(HttpStatusCode.Created, orderData);
string uri = Url.Link("DefaultApi", new { customerID = orderData.ID });
response.Headers.Location = new Uri(uri);
return response;
}
A few more remarks:
If it is indeed a 1:n relationship, you probably need a property Product.OrderId.
The Order class should not have any reference to Product except for the list.
Quantity and Price should most likely not be String but numerical values, e.g. decimal.
If Order.ID is your primary key, then having Order.Order_ID is really confusing. Consider renaming it to Order.Order_Number.
public class Order
{
public string User_Id { get; set; }
public string Key_Code { get; set; }
public string OrderID { get; set; }
public string Name { get; set; }
public Product[] ProductDetails { get; set; }
}

Resources