Are ElasticSearch query results cached? - c#

I'm using ElasticSearch 2.3 and ASP.NET web application. I'm calling ElasticSearch through its REST API using C# HttpClient.
I have a problem when trying to add new values to an array.
Here's essentially the queries that I'm performing:
Step 1: Get note
POST /notes/note/_search
{
"query" : {
"term" : { "_id" : 1 }
}
}
There's only 1 note and the result shows that the note contains an empty array of attachments
Step2: Update note attachments array
POST: /notes/note/1/_update
{
"doc" : {
"Attachments" : [ "Test" ]
}
}
Step3: Get note again
POST: /notes/note/_search
{
"query" : {
"term" : { "_id" : 1 }
}
}
The result shows that the note still contains an empty Attachments array.
However, when I Search/MatchAll from Kibana, I see that the Attachments array has been updated with the new item. However, when running all those steps from ASP.NET, I'm not getting the updated document when immediately searching for it right after the update.
Is this caused by some kind of caching ?
What must I do to get consistent state of the document after an update has been performed ?
Any help appreciated!
Thanks

What could be happening is that the refresh did not come by yet. Than you are able to do a get by id, but the update is not available yet for search. So force a refresh before executing the search. When inserting a lot of documents this does have a performance impact. But for testing you should be fine.

Related

Transforming JSON template based on JSON values posted into API

I have got a requirement of building an azure function which transforms data in our COSMOS DB based on the value posted by a calling service.
So consider this JSON template
{
"processExecutionId": 1000,
"processId": "$PID",
"parentProcessId": 10,
"objectNameTag": "$ObjectName",
"objectName": "bbps.fx",
"processStartedOn": "$startedOn",
"processCompletedOn": "$CompletedAt",
"processExecutionStatusId": 2,
"configurationPayload": "Actual Config Payload with replaced values by the orchestrator or payload read service",
"objectMetadata": {
"jsonPayLoadRead": {
"messages": "$Message"
},
"writeToDB": "$IsWrite"
}
}
This is something we in COSMOS corresponding to a key.
So when a requester application posts that Key it has a JSON object in its body like this
{
"processStartedOn": "2022-01-25 10:10:32",
"processCompletedOn": "2022-01-25 10:20:25",
"objectMetadata": {
"jsonPayLoadRead": {
"messages": "Data uploaded"
},
"writeToDB": "True"
}
}
So the method posting parameters for the template expecting a response from the API after replacing those variables in the template with the values.
The JSON template is not always the same structure. Otherwise we can atleast define a class and can deserialize into it. So what ever the key posted our service needs to take the corresponding JSON template from COSMOS and do the transformation.
So dont know how to handle it the best way or is there is any way to handle this process within COSMOS itself rather than trying using C#.
Please share your thoughts
You can always add a TemplateType property in your class so that you know the various options you have and based on that you know what class to use, there are also ways to stream from cosmos directly without using classes at all but it depends a little what you are trying to achieve if you just need to hand over to another app or not then you can stream from cosmos without even knowing what the structure is

How do I make sure that the execution of the webpage is only proceeded if the api result is returned?

In
ngOninit() of the app.component, we have called an api that basically returns the true/false. Based on that, 'type' a class is injected into the document.body i.e. IsVisible. And in the Sass of app.component it disables the logos and other contents in the web page.
api call
const res= app.services.getIsActiveType().toPromise();
document.body.ClassList.Add(res.type);
in sass
body {
&.Type{
logos {
dispaly: none;
}
}
}
But when deployed to the real server we have an issue with the speed which results in calling and returning the response being delayed by around 6,7 seconds hence the content is visible until the webapi returns a result.
Now, shall we improve the speed of the server or change the logic because the particular role should not see those contents but the slow speed results in showing it for a while.
What should I do? Even if a speed is improved I cannot rely on that.
I searched and solutuon is to use resolvers but I don't know much about that since new to angular.
Approach 1: you can invert the behavior of the CSS class so that it shows instead of hides stuff and keep things hidden by default
Approach 2: you can use APP_INITIALIZER to wait for API's response, the special thing about APP_INITIALIZER is that it will be called even before root component's initialization and angular will wait until it gets resolved, here's the sample code:
const initializer = (apiService: ApiService) => {
return () => {
return apiService.getIsActiveType()
.then(res => res.json())
.then(res => {
document.body.classList.add(res.type);
});
};
}
register this initializer in app module like this:
#NgModule({
providers: [
{
provide: APP_INITIALIZER,
useFactory: initializer,
deps: [ApiService],
multi: true,
},
],
})
export class AppModule { }
if you go with this approach, also optimize API response so that user is not staring at a blank white screen for like 6-7 seconds
Please, try something like:
app.services
.getIsActiveType()
.subscribe( (result:any) => {
document.body.ClassList.Add(result.type);
} );
I would recommend the following:
If content is authorized for a specific user role, that content should not be visible until the role is confirmed.
Utilize Angular's template resources like *ngIf if you want to keep content hidden from the view. Hiding it with CSS is not secure.
I would recommend using observables instead of .toPromise() as this feature will eventually become deprecated in RxJS 7.x (Angular still uses 6.x for now.)

Why does lazy loading in dotnet core 5 add unnecessary elements to the response?

I have a dotnet core web api that returns a list of candidates when I navigate to that endpoint. The candidate class has navigation properties that reference related data. I have also enabled Lazy Loading via the proxies package. The issue? I'm having is that the JSON response is a lot different from what I was expecting.
This is the response I get:
{
"$id":"1",
"$values":[
{
"$id":"2",
"candidateId":2,
"constituencyId":1,
"constituency":{
"$id":"3",
"constituencyId":1,
"name":"",
"parish":"",
},
"member":{
"$id":"4",
"memberId":2,
"prefix":"Mr",
"firstName":"John",
"middleName":"",
"lastName":"Brown",
"suffix":"",
"partyId":2,
"position":"",
"joinDate":"1995-06-05T10:00:00"
}
},
{
"$id":"5",
"candidateId":1,
"constituencyId":2,
"constituency":{
...
},
"member":{
...
}
}
]
}
Why does it insert additional $id properties and a $values array? When I try to load the data into a Next.js table and display data from the nested objects, such as "member" and "constituency"; I get an error of undefined.
The table accepts the data in the following format:
<Table data={data.$values} >
I'm able to access top-level properties such as the "candidateId" with ease. However, if I try to access "position" within "member" I get an error that "member" is undefined.
<Table.Column prop={member.position}/> //member undefined
<Table.Column prop={constituency.name} /> //constituency undefined
Since the table takes the data and iterates over the objects in the $values array, I would assume that I should be able to directly access the properties in member or constituency
Even though I say the additional elements are unnecessary, I'm guessing that they are needed.

Angular Material AutoComplete Not Loading Options MVC

I am working on my AutoComplete widget, using Angular JS - Material, in C# ASP.NET MVC.
In this example, I'm trying to get an AutoComplete of States to work. I started with this tutorial, but need to have the options come from the database (at this point, just static list of options in the controller).
Here is a link to my current code (relevant files).
When I run the code, I can see that the list of objects from the controller are pulling through properly - an array of 4 objects, each with an Id and a Name (as shown in my controller method). However, the options are not being loaded into the input form.
When I click into the textbox, I get an "option" that says No states matching "" were found. If I type in 'a', I get the "option" that says No states matching "a" were found. This is what I would expect to happen if there actually were no matching results.
My question: How do I change my code to load the options with what I'm pulling from the controller?
Thanks in advance!
Here's a screen shot of the results:
Here's the key JavaScript/AngularJS code:
//TODO: Replace data.json with /Home/GetStates
$http.get('data.json')
.then(function(response) {
self.states = response.data.map(function(state) {
return {
value: state.Name.toLowerCase(),
display: state.Name
};
});
});
You'll need to replace 'data.json' with '/Home/GetStates' for it to call your backend MVC JSON RESTful API Service. Note that I also left the functions querySearch(query) and createFilterFor(query) in place and changed self.states=loadStates() to self.states=null since the $http.get() service will now load the states.
I did test your C# MVC controller code and everything looks good with it.
Here's a working Plunker, http://plnkr.co/edit/tDC6KcO1O8VSGwVghBo7?p=preview.
Hope this helps. Let me know if you need anything else.
Here's what I did to fix the problem:
Changed to POST
Set variable = result, then returned the results
Here's the code:
function querySearch(query) {
if (query == undefined) {
console.log("invalid");
return;
}
$http({
method: 'POST',
url: self.URL_Get + query,
searchTerm: query
}).then(function(response) {
self.states = response.data;
});
return self.states;
}

Return latest article in news control asp.net c#

I have got a news control which displays a news article when the id is selected and returned into the url. The problem is that if i go to the page without the id parameter in the url then the page is blank. What I want to do is display the latest news article if no id is selected.
I have hacked it atm to display id 157.
Any help would be great.
Thanks
protected Article _article;
protected Article Article
{
get
{
if (null == _article && null != Request.QueryString["id"])
{
_article = Article.GetById(Int64.Parse(Request.QueryString["id"]));
}
else
{
_article = Article.GetById(Int64.Parse("157"));
}
return _article;
}
}
From what i understood, you need to keep track of what is the latest ID. And make use of it here instead of "157".
when ever latest news is published store the new id make it accessible to above code snippet you have shared. Possible ways i think ,
In the session variable store the latest ID
if your code is not load balanced , use staic variable of latest id and update it and let all other access and use it.
Get latest ID info from DB at the place of hardcoding it to 157
if my understanding of your problem is not right. please elaborate your question

Categories

Resources