Suppose I have two columns in my database table as below :
Id Actions
-- -------
id1 [{"Id": "create", "Schema": {"Id": "create", "Type": "Create"}, "Workflow": "basic"}]
I want to extract the value of the Workflow and check if it equals basic, then create a list with the entries in the database that meet this condition.
What I have tried is:
var data = db.Where(wf => (string) JObject.Parse(wf.Actions)["Workflow"] == "basic").AsEnumerable();
Then I check:
if (data.Any())
{
// do something
}
But the if statement throws me the following error:
System.ArgumentNullException: Value cannot be null.
Use JArray.Parse:
var data = db.Where(wf => (string) JArray.Parse(wf.Actions)[0]["Workflow"] == "basic")
.AsEnumerable();
Your json object is actually json array, so you need to parse it to JArray.
Then, when getting the value from JToken, you need to call .Value<string>, then you can compare it to "basic" string.
var data = db.Where(wf => JArray.Parse(wf.Actions).FirstOrDefault()?["Workflow"].Value<string>() == "basic").ToList();
Related
I have collection where each document has two fields:
"Field1" - string value
"Field2" - object value with "Field2.Field3(object).Field4(string)".
Now I'm trying to take all documents for which "Field2.Field3" is not null. When I do sth like this for Field1 then it works:
query = Builders<MyDocument>.Filter.Ne(t => t.Field1, null)
However, when I do the same but for "Field2.Field3":
query = Builders<MyDocument>.Filter.Ne(t => t.Field2.Field3, null)
then I got an error "command find failed". Where is the problem?
Hi I need help finding a value from a Object list that I created form aJSON file :
JSON Structure :
{
"mp": "1",
"mpuus": [
{
"id": "100",
"tpuus": [
"000000001",
"000000002"
]
},
{
"id": "101",
"tpuus": [
"00000003"
]
}
]
},
{
"mp": "2",
"mpuus": [
{
"id": "200",
"tpuus": [
"0000004"
]
}
]
},
I convert JSON to
RootMedicationMapping object.
List<rootMedicationMapping> = JsonHandler.DeserializeJasonArrayFromFile<RootMedicationMapping>(#"JSON File PATH");
I would like to search the list of rootMedicationMapping by the tpuu value and get the mp value.
e.g the value I am passing is tpuu = 000000002, I want to get back the mp value (1 in this case)
This am trying the below syntax but it isthrowing me
'Cannot implicently convert type 'string' to 'bool'
var mpId= rootMedicationMapping.Find(x => x.MPUUs.Find(y=>y.Tpuus.Find(z=>z.Equals("tpuu value"))));
The parameter of List.Find(Predicate) needs to be a Predicate which is a delegate that takes in an instance of the object you're searching and expects a bool returned specifying if the object matches. Currently, in the Predicate of your inner Find calls you're simply returning the result of another Find call, which is a string and not the expected bool, resulting in the error you're seeing.
To fix this, you just need to make sure the Predicate arguments return bool. With what you have, you can just add checks whether or not the inner Find calls return null:
var mpId =
rootMedicationMapping.Find(x =>
x.MPUUs.Find(y =>
y.Tpuus.Find(z =>
z.Equals("tpuu value")) != null) != null)?.mp;
And you could also write this using LINQ, allowing the null checks to be handled by Any:
var mpId =
rootMedicationMapping.FirstOrDefault(x =>
x.MPUUs.Any(y =>
y.Tpuus.Any(z =>
z.Equals("tpuu value"))))?.mp;
for some legacy code, I need to return a list of rows than come from a list of the element, but, the client needs it without the property name.
This is what I need. (I know that inside this JSON return, it's an array list then it's not a valid JSON, but is the way that needs to be received by the front end I don't know why
{ "success":true,"msg":"","draw":"1","recordsTotal":14,"recordsFiltered":14,
{ "data":
[
["Xiaomi","Redmi 8","10","6.0.1","","sadsadasd"],
["Xiaomi","Redmi 8","10","6.0.1","","sadsadasd"],
]
}
This is what I got now
{"success":true,"msg":"","draw":"1","recordsTotal":14,"recordsFiltered":14,
"data" :[
{"Brand":"Xiaomi","Model":"Redmi 8","Version":10,"App":"4.3.3","Phone":"","AsignedUSer":"ceererer"},
{"Brand":"Xiaomi","Model":"Redmi 8","Version":10,"App":"4.3.3","Phone":"","AsignedUSer":"ceererer"},
]
}
And this is the code how I am retrieving the data
return new JsonResult(new { success = true, msg = "", draw ="1", recordsTotal = listToReturn.Count(), recordsFiltered = listToReturn.Count() ,
data = listToReturn ,
});
You could project your list into arrays to extract the property values:
var data = listToReturn
.Select(d => new string[]{d.Brand, d.Model, d.Version, etc..})
.ToList();
Note that a "JSON" content without the property names will be a not valid JSON document.
What you need seems to be more like a CSV-like response.
Have you tried to format the result as CSV?
Hello I am a newbie on ElasticSearch and need help. I'm working with c# (thought I could use a QueryRaw in String I think...).
Below the scenario:
Data
{
"id": "1",
"title": "Small cars",
"tagsColours": ["grey",
"black",
"white"],
"tagsCars": ["Suzuki",
"Ford"],
"tagsKeywords": []
},
{
"id": "2",
"title": "Medium cars",
"tagsColours": [],
"tagsCars": ["VW",
"Audi",
"Peugeot"],
"tagsKeywords": ["Sedan"]
},
{
"id": "3",
"title": "Big cars",
"tagsColours": ["red",
"black"],
"tagsCars": ["Jeep",
"Dodge"],
"tagsKeywords": ["Van",
"Big"]
}
Objective
Id' like to apply filters on tags columns based on users' selection. the values will be populated in the tagsXXX array columns withselected values.
if parameter array value is not empty then the result should contain at least one instance. Same for every parameter array. the more the parameters have values, the more specific search should be done
if at least there's one value coming from the parameter that matches amongst all values in any document's tag column array, then get that document.
but if there's another value on another tagsXXX array then it should take it into account.
if the tag parameter array has no values, then disregard that filter
Desired responses
A) If user select only 1 tag Color (i.e= black) as formatted below:
{
id: "",
title: "",
tagsColours: ["black"],
tagsCars: [],
tagsKeywords: []
}
I'd like to get documents with Id=2 and id=3 since they have black in their tagsColours and disregard tagsCars and tagsKeywords since there are no values on the parameters
B) If user select only 2 diff tags (i.e= colour=black and cars= audi, and mercedez benz) as formatted below:
{
id: "",
title: "",
tagsColours: ["black",
"yellow"],
tagsCars: ["Audi",
"Mercedes Benz"],
tagsKeywords: []
}
I'd like to get documents with id=2 since it found black on tagsColours and it found Audi in tagsCars, AND it should not pull document id=1 because
even when black is on tagsColours, none of paramters values (audi, mercedez benz) is on its tagsCars values
Hello everyone, I'm having issues when trying to search on ElasticSearch and look for in arrays with values, and when parameters have no values.
If anyone could helpe me on this I'd appreciatte.
I did this:
termsQuery = Query<StructuredData>.Terms(t => t.Field(f =>f.TagsColours).Terms(dataToSearch.TagsColours));
termsQuery = termsQuery && Query<StructuredData>.Terms(t => t.Field(f =>f.TagsCars).Terms(dataToSearch.TagsCars));
and I stopped here (did not add third filter) because I could not mix two filters together
dataToSearch has the values from parameters (same structure object, cause .Search makes me do that here .Search()
var settings = new ConnectionSettings(node);
var response = new ElasticClient(settings)
.Search<StructuredData>(
s => s.AllIndices()
.AllTypes()
.From(0)
.Size(50)
.Query(_ => termsQuery)
);
But I'm having problems when using more than 1 filter..
any ideas? is ".Terms" the correct property?
If you are using regular mappings on ES 5 > This will get you results you want. If not you will need to change the mapping.
QueryContainer query = null;
if(dataToSearch.TagsColours != null && dataToSearch.TagsCars.Length > 0)
{
query = Query<StructuredData>.Terms(t=>t.Field("tagsColours.keyword").Terms(dataToSearch.TagsColours));
}
if(dataToSearch.TagsColours != null && dataToSearch.TagsCars.Length > 0)
{
var q = Query<StructuredData>.Terms(t=>t.Field("tagsCars.keyword").Terms(dataToSearch.TagsCars));
query = query == null ? q : query && q;
}
if(dataToSearch.TagsKeywords != null && dataToSearch.TagsKeywords.Length > 0)
{
var q = Query<StructuredData>.Terms(t=>t.Field("tagsKeywords.keyword").Terms(dataToSearch.TagsKeywords));
query = query == null ? q : query && q;
}
The problem you are having is that the term query is done on a non-analyzed value and default text fields use standard analyzer. As of 5 they added keyword sub field that uses the keyword analyzer it essentially just places the terms as is and you can do a search by raw values. The standard analyzer dose tokenization for words and lowercases all the terms so it was unable to find Audi because the term was audi. If you want to just lowercase the input string this will not solve the Mercedes Benz problem since in the standard terms this will became mercedes a benz terms two terms instead of one in other words terms will return results if you put mercedes or benz but not mercedes benz. If you want to da a case insensitive search with the match query you will need to add a custom analyzer.
This is my MongoDB Data structure:
public class Part : ICloneable
{
string _id;
ObservableCollection<DataElement> PartData;
ObservableCollection<DataElement> SensorData;
}
public class DataElement: ICloneable
{
string description;
string[] values;
}
Using Linq I want to read all Parts $projected/reduced on the elements of SensorData, PartData and ResultData with a specific description.
Example:
Part{
_id: id1,
PartData[
{description: "des1", values: "val1"},
{description: "des2", values: "val2"}
],
SensorData[
{description: "des3", values: "val5"},
{description: "des4", values: "val2"},
{description: "des5", values: "val2"}
]}
should be projected/reduced on all elements having the description "des2", "des4" and "des5", so that the data read looks like
Part{
_id: id1,
PartData[
{description: "des2", values: "val2"}
],
SensorData[
{description: "des4", values: "val2"},
{description: "des5", values: "val2"}
]}
Each description is unique, but not every Part contains all descriptions.
Is there an easy solution for doing this without any $unwind/SelectMany? Something like
Select(p => p.PartData[] where p.PartData.Description == specifiedDescription),
p => p.SensorData[] where p.SensorData.Description == specifiedDescription))
but including the complete array element, while excluding the others and for PartData and SensorData?
Edit:
After the answer by Veeram I tried to implement the following:
parts = db.GetCollection<Part>("Part");
var pipeline = parts.Aggregate()
.Project(p => new
{ PartData = p.PartData.Where(d => d.Description == specifiedDescription),
SensorData = p.SensorData.Where(s => s.Description == specifiedDescription)
}) ;
var query = pipeline.ToEnumerable().AsQueryable();
var returnParts = new ObservableCollection<Part>(query);
but this causes pipeline to be an anonymous IAggregateFluent<'a> instead of an IAggregateFluent<Part>, which makes query to be an anonymous IQueryable<'a> and therefore leading to the compile error "cannot convert from anonymous IQueryable<'a> to IQueryable<Part>" at the insertion of query as argument for the constructor of ObservableCollection<Part>().
Without the $select the variables aren't anonymous anymore, but of class <Part> and the compile error doesn't occur. Obviously the $select changes the class of the aggregation.
How is it possible to solve this error? My idea would be to make the $project without generating a new class, but rather resetting some fields of the current class <Part>, but how can this be achieved?
You can use $filter operator in $project stage with aggregation pipeline.
var pipeline =
collection.
Aggregate()
.Project(
p => new {
PartData= p.PartData.Where(d => d.Description == specifiedDescription),
SensorData= p.SensorData.Where(s=> s.Description == specifiedDescription)
}
);