ElasticSearch-Net NEST search - elasticsearch

I'm using NEST lib, and very basic setup according to the document. I've added index, mapping, etc.
But when I try to do search it always gives me, "An item with the same key has already been added". It confused me alot on what the error means.
var result = client.Search<Contact>(s => s
.AllIndices()
.From(0)
.Size(10)
.Query(q => q
.MatchAll())
);
Here is the Contact:
public class Contact
{
public Guid Id { get; set; }
public Guid TenantId { get; set; }
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime ModifiedDate { get; set; }
public IList<string> Emails { get; set; }
}

You likely have a contact in elastic with the same email address twice. You could change the Email property to a string array perhaps?

Related

How to handle char property properly in Hotchocolate Graphql 12.0?

I am trying to implement filtering on Resource table which has MartialStatus of char property in DDL of database.Let my show you my approach first. In my program.cs file, i have the following:
using LIS.ResourcePlanningSystem.API;
using LIS.ResourcePlanningSystem.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<RpsDbContext>(options => options.UseLazyLoadingProxies().UseNpgsql(builder.Configuration.GetConnectionString("RPSDbContext")));
builder.Services.AddGraphQLServer().
RegisterDbContext<RpsDbContext>().
AddQueryType<Query>().
AddProjections().
AddFiltering().
AddSorting().
BindRuntimeType<char, StringType>().
AddTypeConverter<char, string>(from => from.ToString()).
AddTypeConverter<string, char>(from => from.ToCharArray()[0]);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.MapGraphQL("/graphql");
app.Run();
Here is my a model Register.cs which has "MaritalStatus" char property.
public class Resource
{
public int Id { get; set; }
public string? FirstName { get; set; }
public string? MiddleName { get; set; }
public string? LastName { get; set; }
public string? FullName { get; set; }
public char? MaritalStatus { get; set; }
public virtual Gender? Gender { get; set; }
public virtual Education? Education { get; set; }
public int? InstitutionId { get; set; }
public string? PerStreet { get; set; }
public DateTime? OfficeJoinDt { get; set; }
public virtual Grade? Grade { get; set; }
public int? PositionId { get; set; }
public virtual Department? Department { get; set; }
public virtual ClientType? ClientType{ get; set; }
public int? ExpOut { get; set; }
public string? ResignedFlag { get; set; }
public string? Email { get; set; }
public virtual BloodGroup? BloodGroup { get; set; }
public virtual ResignedRemarks? ResignedRemark { get; set; }
public virtual Source? Source { get; set; }
}
Now, the program runs just fine until i add [UseFiltering] on the Resource table in query.cs file.
[UseFiltering]
[UseSorting]
public IQueryable<Resource>? GetResources(RpsDbContext context) => context.Resources;
The error i am getting is this:
HotChocolate.SchemaException: For more details look at the `Errors` property.
1. For more details look at the `Errors` property.
1. The type of the member MaritalStatus of the declaring type Resource is unknown
If i remove the [UseFiltering] [UseSorting], the program works fine. I think the problem is related to filtering on resource table. Filtering also work fine on all the other tables which doesn't have char property in its schema definition. Someone has opened a bug issue on github [here] . Tried to solve reading this issue but no luck. Could somebody please tell me how can i get around this problem?

How to update an existing object in a many to many relationship (.Net 5)

I have been using the .Net 5 and EF Core 5 for a small web app. Given EF Core 5 supports many - many out of the box there is no need for a joining table.
I've run into an issue when updating a object that already exists in the DB. For my app I have Athletes and Parents which have the many - many relationship.
public class Athlete
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public string Email { get; set; }
public string ContactNumber { get; set; }
public string Street { get; set; }
public int Postcode { get; set; }
public string City { get; set; }
public StateEnum State { get; set; }
public DateTime DateofBirth { get; set; }
public DateTime DateSignedUp {get; set;}
public virtual ICollection<Parent> Parents { get; set; }
}
public class Parent
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public string Email { get; set; }
public string ContactNumber { get; set; }
public string Street { get; set; }
public int Postcode { get; set; }
public string City { get; set; }
public StateEnum State { get; set; }
public DateTime DateofBirth { get; set; }
public DateTime DateSignedUp {get; set;}
public virtual ICollection<Athlete> Athletes { get; set; }
}
When I try to update the existing athlete that has a relation ship with two other parents I get an error:
Violation of PRIMARY KEY constraint 'PK_AthleteParent'. Cannot insert
duplicate key in object 'dbo.AthleteParent'. The duplicate key value
is (31, 1)
[HttpPost]
public async Task<ActionResult<Athlete>> PostAthlete(Athlete athlete)
{
_context.Athletes.Update(athlete);
await _context.SaveChangesAsync();
return Ok(athlete));
}
From what I can tell when entity tries to update my Athlete it tries to insert new rows into the joining table even though the parents already exist in there. Is there a way to get entity to remove any records when the relationship is updated? Or is there a way to tell entity to take update the joining table to match the Athlete object that is passed in?
Given a simple example like this:
public class Foo {
Guid Id { get; set; }
ICollection<Bar> Bars { get; set; }
}
public class Bar {
Guid Id { get; set; }
ICollection<Foo> Foos { get; set; }
}
You can call clear() on a tracked instance of Foo, and then re-add the Bar instances that you want assigned. I've found this is a nice way to avoid the constraint exception - much easier than manually trying to figure out what Bars have changed.
var foo = context.Foos.Include(x => x.Bars).FirstOrDefault(x => x.Id == someGuid);
foo.Bars.Clear();
foo.Bars.Add(bar1);
foo.Bars.Add(bar2);
...
context.Update(foo);
context.SaveChanges();

ElasticSearch retrieve more recent X lines using NEST

I want to retrieve more recent X lines from elasticsearch using NEST, but when I use .Sort() it will return 0 documents. If I remove Sort() it will return documents but not the most recent ones.
Any idea how to retrieve most recent logs lines from elastic or what i am doing wrong?
var result = elk.Search<FileBeatDto>(x => x
.From(0)
.Index("filebeat-*")
.Type(type)
.Query(q =>
q.Match(qs => qs.Field("fields.asset_tag").Query(asset_tag)) &&
q.Match(qs => qs.Field("message").Query(filter))
)
.Take(lines)
.Sort(ss => ss.Descending(p => p.timestamp))
);
timestamp and version are retrieved as null. Not sure it is because in elastic they are #timestamp and #version.
public class FileBeatDto
{
public DateTime timestamp { get; set; }
public string datetime { get; set; }
public DateTime received_at { get; set; }
public int offset { get; set; }
public string version { get; set; }
public string input_type { get; set; }
public int count { get; set; }
public Beat beat { get; set; }
public string host { get; set; }
public string source { get; set; }
public string message { get; set; }
public string type { get; set; }
public object fields { get; set; }
public List<string> tags { get; set; }
}
type is well defined to the type of document that is not the problem if i remove the sort it returns the documents fine.
I get this error: No mapping found for [timestamp] in order to sort on

raven query on object type throws exception

document Structure:
class UserAccountInfo
{
public String Id { get; set; }
public AccountType AccountType { get; set; }Servicetax
public String MainAccountMobileNo { get; set; }
public UserStatus Status { get; set; }
public String EmailId { get; set; }
public String DisplayName { get; set; }
**public Object User { get; set; }**
}
object stores instance of any type that is mentioned in Account type. the type that is stored in the object can be found using Accountype for ex; if Accountype is customer then instance stored in the object will be AccountinfoCustomer and so on. So using that I've tried to query but getting the following exception from raven.
var Result = sess.Query<UserAccountInfo>().Where(x => x.AccountType == usertype && ((AccountInfoCustomer)x.User).Customerstatus == CustomerStatus.Pending);
{"Url: \"/indexes/dynamic/UserAccountInfos?query=AccountType%253ADistributor%2520AND%2520User).Customerstatus%253APending&start=0&pageSize=128&aggregation=None\"\r\n\r\nSystem.ArgumentException: The field ')_Customerstatus' is not indexed, cannot query on fields that are not indexed\r\n at Raven.Database.Indexing.Index.IndexQueryOperation.AssertQueryDoesNotContainFieldsThatAreNotIndexes()
This should work. Tested in current stable RavenDB 2.0.2230.
Tests here: https://gist.github.com/4692351
Are you on an older version?

LINQ query not returning all results due to null value on Entity Framework Core only

I have two rows of test data and am able to pull back the first row with no problems but can't get the second row to return. Digging around and testing shows that this is probably due to the AppovedByID column being null in the row that is not being returned. I have looked but can't figure out how to modify my LINQ query so it will return all rows even if the child table can't be linked in due to a null value.
The Query:
public JsonResult ChangeOrders()
{
var ChangeOrdersList = _DbContext.ChangeOrders
.Include(co => co.ApprovalStatus)
.Include(co => co.ApprovedBy)
.Include(co => co.AssignedTo)
.Include(co => co.CreatedBy)
.Include(co => co.CurrentStatus)
.Include(co => co.Impact)
.Include(co => co.Priority)
.Include(co => co.ChangeType)
.Select(co => new ChangeOrderListVM()
{
ApprovalStatus = co.ApprovalStatus.Name,
ApprovedBy = string.Concat(co.ApprovedBy.FirstName, ' ', co.ApprovedBy.LastName),
AssignedTo = string.Concat(co.AssignedTo.FirstName, ' ', co.AssignedTo.LastName),
CreatedBy = string.Concat(co.CreatedBy.FirstName, ' ', co.CreatedBy.LastName),
CurrentStatus = co.CurrentStatus.Name,
DateApproved = co.DateApproved,
DateCompleated = co.DateCompleated,
DateCreated = co.DateCreated,
DateStarted = co.DateStarted,
EstimatedEndDate = co.EstimatedEndDate,
EstimatedStartDate = co.EstimatedStartDate,
ID = co.ID,
Impact = co.Impact.Name,
Name = co.Name,
Priority = co.Priority.Name,
Reason = co.ReasonForChange,
Type = co.ChangeType.Name
}).ToList();
return Json(ChangeOrdersList);
}
ChangeOrders:
public class ChangeOrder
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public short? ApprovedByUserID { get; set; }
public byte ApprovalStatusID { get; set; }
public short AssignedToUserID { get; set; }
public short CreatedByUserID { get; set; }
public byte CurrentStatusID { get; set; }
public DateTime? DateApproved { get; set; }
public DateTime? DateCompleated { get; set; }
public DateTime DateCreated { get; set; }
public DateTime? DateStarted { get; set; }
public DateTime EstimatedStartDate { get; set; }
public DateTime EstimatedEndDate { get; set; }
public byte ImpactID { get; set; }
public byte PriorityID { get; set; }
public byte TypeID { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string ReasonForChange { get; set; }
[ForeignKey("ApprovalStatusID")]
public ChangeApprovalStatus ApprovalStatus { get; set; }
[ForeignKey("ApprovedByUserID")]
public User ApprovedBy { get; set; }
[ForeignKey("AssignedToUserID")]
public User AssignedTo { get; set; }
[ForeignKey("CreatedByUserID")]
public User CreatedBy { get; set; }
[ForeignKey("CurrentStatusID")]
public ChangeStatus CurrentStatus { get; set; }
[ForeignKey("ImpactID")]
public ChangeImpact Impact { get; set; }
[ForeignKey("PriorityID")]
public ChangePriority Priority { get; set; }
[ForeignKey("TypeID")]
public ChangeType ChangeType { get; set; }
}
Users:
public class User
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public short ID { get; set; }
[Required]
public string ADUserName { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string Email { get; set; }
[Required]
public string Phone { get; set; }
[Required]
public DateTime LastUpdated { get; set; }
}
EDIT:
This is apparently unique to Entity Framework 7 (AKA Core) as it works fine in EF 6. I am in fact using EF7 and as an additional test I updated a single line
ApprovedBy = string.Concat(co.ApprovedBy.FirstName, ' ', co.ApprovedBy.LastName),
and changed it to this
ApprovedBy = "",
and all the rows are returning so I then tried to do
ApprovedBy = (co.ApprovedByUserID.HasValue) ? string.Concat(co.ApprovedBy.FirstName, ' ', co.ApprovedBy.LastName) : "",
but that give a very odd error:
incorrect syntax near the keyword 'is'
This is a bug in the library. I have reported the bug for fixing in the next version on github

Resources