Is it possible to map a spring data entity field to another field in elasticsearch? - spring-data-elasticsearch

I have this model:
public class Foo{
#Field(type = FieldType.String, store = true)
String color;
}
right now it maps to the field "color" in elasticsearch document. Can I map it to another field: "shirtColor"? Maybe through an annotation?

spring-data-elasticsearch uses Jackson Object Mapper to serialize the POJO into json. You can use #JsonProperty attribute if you want to change the name of field which is store in Elastic Search.
public class Foo{
#Field(type = FieldType.String, store = true)
#JsonProperty("shirtColor")
String color;
}
However you will loose the benefit of using findBy* methods while querying the data back from elastic search and you will have to write your own custom queries to fetch the data.

Related

Spring Data ElasticSearch: Save document where some fields are dynamic

I have a document I need to save in elastic search where some fields are dynamic, in a HashMap, and some fields I know in advance and can annotate with #Field and so on.
So something like this:
public MyClass {
private String fieldA;
private String fieldB;
private Map<String, Object> dynamicFields;
}
How would I do this? I don't know in advance, which keys will be contained in dynamicFields.
I would also like to define the mapping for the values in dynamicFields, so for instance save dates as dates and not as timestamps.
Is dynamic field mapping the way to go? If so, where can I find examples for that?

Entity Framework call best way to call a another api

Building an api around a db and as part of this we'll be calling another api and joining data in that api to the database for viewing but not storing the data in the current database. My question is if this.
In my data model I have
public class server
{
public Int32 ServerID {get;set;}
public string ServerName {get;set;}
...
}
If I add api columns with to the server object
public string ServerMemory
That of course returns and invalid column name because this is data from the api that is not in the database table.
I see a few options
Create a view within the database structure which has some blank columns and reference that within my data model.
Create another object within my data model and then reference it using virtual using something like the method mentioned here: https://jeremiahflaga.github.io/2020/02/16/entity-framework-6-error-invalid-column-name-_id/
Create another object and a cast to cast the Server object to this other object.
Is there another simpler way to reference a foreign field within an object in a data model?
Thank you.
I found this so anyone else who needs to add a column to a datamodel that does not exist in the database
using System.ComponentModel.DataAnnotations.Schema;
then you can use this:
[NotMapped]
public virtual string RoleDesc { get; set; }
Still curious if this is the best way. I guess that really revolves around your goals.

Customize swagger schema for a nested type using swashbuckle

I have an api (ASP.NET Core 3.0) that allows users to search a document database using various query parameters to filter and order the results. One of the parameters is an Order parameter that defines how to order the results. The acceptable values are limited to the values of an enum.
I now need to add more behavior to the enum, so I re-wrote it as an Enumeration Class so that I can add object-oriented behavior to it. The problem I now have is that Swashbuckle flattens out the properties of the Enumeration rather than leaving it as a single parameter. Here are my enumeration and parameter classes:
// Enumeration
public class DocSearchOrder : Enumeration {
public static readonly DocSearchOrder DocType = new DocSearchOrder(2, nameof(DocType));
public static readonly DocSearchOrder DocTypeDesc = new DocSearchOrder(3, nameof(DocTypeDesc));
public static readonly DocSearchOrder DocDate = new DocSearchOrder(4, nameof(DocDate));
public static readonly DocSearchOrder DocDateDesc = new DocSearchOrder(5, nameof(DocDateDesc));
public DocSearchOrder(int value, string name) : base(value, name) {
}
}
// Search Parameters
public class DocSearchParameters {
public DocSearchOrder? Order { get; set; }
// Lots of other search parameters
}
Then the method that uses it:
public async Task<IActionResult> GetAsync([FromQuery] DocSearchParameters searchParams) {
// Do the search
}
Swashbuckle flattens searchParams.Order into DocSearchOrder.Id and DocSearchOrder.Name.
The behavior I want to achieve is for my Swagger UI to continue to show a dropdown of the available values (DocSearchOrder.Name) that a user can select from with the parameter named "Order". You then pass one of those string values and a custom model binder converts the string to the Enumeration class instance.
I've tried writing a custom IOperationFilter but that only seems to work for modifying the schema of types passed to the GetAsync method, I can't intercept the schema generation for searchParams.Order. I thought what I'd be able to do is somehow intercept the schema generation for any property that is an Enumeration and generate an enum schema for it instead of an object schema, but I don't know how to intercept it.
So my question is: is there a way to customize the schema generation for a nested type? Or is there another way to go about this and I'm doing it all wrong? :)
How about a regular enum:
public enum DocSearchOrder
{
DocType = 2,
DocTypeDesc = 3,
DocDate = 4,
DocDateDesc = 5
}
I think that would that be easier, and there should not give you much trouble
Here is an example from one of mine:
http://swagger-net-test.azurewebsites.net/swagger/ui/index?filter=TestEnum#/TestEnum/TestEnum_Get

How to store a map or json object as a property in neo4j?

I'm trying store a map or json object as a property in Neo4j, but it doesn't work.
That's a limitation of node properties right now. You have a few workarounds to choose from.
You can turn your json object into a string and save it as a property. You can use APOC Procedures to convert JSON strings to and from Cypher map objects.
You can instead save the map properties as properties on the node, though that loses the grouping you would get from the object itself.
If #2 isn't enough, you could also alter your graph model so the data in the JSON object corresponds to graph objects, nodes and properties related to the original node.
Storing a map as properties is supported by neo java OGM library. The library will unwind your map to graph node properties if you annotate the java class field with #Properties.
Class:
#NodeEntity
public class DataNode {
#GraphId
private Long id;
#Properties
private Map<String, String> map = new HashMap<>();
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
}
How to use in java:
DataNode data = new DataNode();
data.getMap().put("testKey", "keyvalue");
data.getMap().put("myKey", "key value for my key");
How it will look in neo:
Notice that if you end up using map keys with dot ".", you might get funky side effects when loading the entity from neo => nested maps. Consider then changing the delimiter in #Properties or change the key.

Data annotation for enforcing that the value stored in a property of type string should actually be a numeric value

Is there an annotation that allows me to say that the following property must have a numeric value and then I want to specify a range for that value?
[DataType.???]
[Range(1990, 2015)]
public string AnniversaryYear { get; set;}
There's a reason I need this to be a string.
check the use of Data Annotations Extensions that simply extends the data annotations that have into the framework, also look this article that show how to use them: Introducing Data Annotations Extensions

Resources