How to use and , or operator(&&, ||) in elasticsearch c# - c#

I am trying to search records in Nest, my conditions are, expiration_date can be null or it can be within some date(ex. 10-20-2018) and effective_date can be some date (09-20-2018).
Below is my query, here I am not able to use || and && operator, either syntax issue, or my approach is wrong, can anyone help me with this?
docs = await _client.SearchAsync<PriceList>(s => s.Index(config.elasticsearchIndex)
.Query(a => a.Bool(c=>c.Should(
d => d.Bool(e => e.MustNot(f=>f.Exists(g => g.Field(h => h.ExpirationDate))))
||
.Query(a => a.DateRange(r => r.Field(field => field.ExpirationDate).GreaterThanOrEquals(forThisRange.fromDate)))
)))
.Query(a => a.DateRange(r => r.Field(field => field.EffectiveDate).LessThanOrEquals(forThisRange.toDate)))
My nest version is 6.4
UPDATED Query:
.Query(a => a.Bool(c=>c.Should(
d => d.Bool(e => e.MustNot(f=>f.Exists(g => g.Field(h => h.ExpirationDate))))
,
d=>d.Bool(e=>e.Must(f=>f.DateRange(r => r.Field(field => field.ExpirationDate).GreaterThanOrEquals(forThisRange.fromDate))))
//i=>i.DateRange
)))
.Query(a => a.DateRange(r => r.Field(field => field.EffectiveDate).LessThanOrEquals(forThisRange.toDate)))
I am not getting any error, but not getting extra record,it is giving correct result + "expiration_date" has less than 10-20-2018,the later should not.

Thanks all for your comments.
I found the solution, replace .Query() with .PostFilter() which resolved the issue. Don't know the exact difference between them, but it worked.
If anybody knows it, please comment it, may be helpful to others.

Related

C# Linq query.Date Between Dates don't work

I tried on two ways to choose to date only from the date frame but still, I get the wrong result. I saw another post but the response doesn't work for me. Please help mine.
List<Measurement> measurementsForTemplate = await databaseCommandContext.CreateSet<Measurement>()
.Include(v => v.MeasuredValues)
.Where(x => x.MeasurementFormTemplateId == command.TemplateId )
.Where(v => v.MeasuredValues.Any(d => d.Time >= command.FromDate))
.Where(v => v.MeasuredValues.Any(d => d.Time <= command.ToDate)).ToListAsync(cancellationToken);
Or I created an object without filtering in the above query and then
var measurementsForTemplateDateLimit = measurementsForTemplate.Where(b => b.MeasuredValues
.Any(d => d.Time >= command.FromDate && d.Time <= command.ToDate)).Select(b => b);
See figure below with solution

How can I include FirstOrDefault child of parent in Entity Framework linq ".Include"

I want to select Evaluation with all his Component and only the first Answers of each component.
QueryFutureEnumerable<Evaluation> deferredEvaluations = db.Evaluations
.Include(e => e.Components)
.Include(e => e.Components.Select(c => c.Answers).FirstOrDefault())
.Where(e => e.Deprecated == false)
.OrderByDescending(e => e.LastModified)
.Future();
I need help figuring how to Include only first Answer child.
Here is what I already tried which does not works:
.Include(e => e.Components.Select(c => new List<Answer>(){ c.Answers.FirstOrDefault()} ))
.Include(e => e.Components.Select(c => new { Answer = c.Answers.FirstOrDefault()}))
.Include(e => e.Components.Select(c => c.Answers.Take(1)))
Note: I'm using Z.EntityFramework.Plus; but I don't think the part of the query that I want to accomplish has anything to do with that.
When it's not workin, "I get the error: The Include path expression must refer to a navigation property defined on the type..."

Elastic Search - Reverse match query

Currently I wrote a query against an elastic server to remove all documents with an old "BatchVersion". After thinking about it, to be safe, I want all records delete that don't equal the current "BatchVersion". Here is my current code
_client.DeleteByQuery<Data.ElasticSearch.Employee>(s => s
.Index(indexName)
.Size(1000)
.Query(q => q.
Bool(b => b.
MustNot(mn => mn.
Match(m => m.Field("BatchVersion").
Query([newVersionId]))))));
When the code is run, no records are deleted. Any ideas?
I had to use Default_Field for it to work. I used kibana to figure it out.
_client.DeleteByQuery<Employee>(s => s
.Index(indexName)
.Size(1000)
.Query(q => q.
Bool(b => b.
MustNot(mn => mn.
QueryString(qs => qs.DefaultField("batchVersion").Query(newVersionId.ToString()))))));

WHERE is not being included in the LINQ-query

Today I ran into a problem with Entity Framework. I'm not sure if this is a weird bug or that i'm doing something wrong. I've already looked all over the forum for any possible solutions, but none I found worked for me.
I have the following LINQ query:
return (from sp in context.ServiceProviders.DefaultIfEmpty()
join pl in context.Platforms on sp.Id equals pl.ServiceProviderId into innerPl
from pl in innerPl.DefaultIfEmpty()
join pp in context.Participants on pl.Id equals pp.PlatformId into innerPp
from pp in innerPp.DefaultIfEmpty()
join ps in context.Paymentsettlements on pp.Id equals ps.ParticipantId into innerPs
from ps in innerPs.Where(ps => ps.ConfirmedOn.HasValue && ps.ExportDate.HasValue && !ps.StatisticsDate.HasValue).DefaultIfEmpty()
select sp).Include(sp => sp.Environment)
.Include(sp => sp.Platforms.Select(pl => pl.Participants.Select(pp => pp.Paymentsettlements.Select(ps => ps.Requester))))
.Include(sp => sp.Platforms.Select(pl => pl.Participants.Select(pp => pp.Paymentsettlements.Select(ps => ps.Payer))))
.ToList();
The result i'm looking for is that i always get the ServiceProvider no matter if there are objects inside the ServiceProvider. I am getting this result at the moment, but the where I've put in the query does not get taken into account. The following where does not make any difference:
innerPs.Where(ps => ps.ConfirmedOn.HasValue && ps.ExportDate.HasValue && !ps.StatisticsDate.HasValue).DefaultIfEmpty()
If the StatisticsDate has a value, those Paymentsettlements also are given in the output.
I've already tried to put the WHERE statement on the context.Paymentsettlements object.
I hope anyone can help me with this problem.
Kind regards,
Rob H
Actually you are doing left join and then selecting ServiceProviders. Here you are getting all providers. Then you are including all child elements: select sp).Include(sp => sp.Environment). This won't work. It will include all rows.
What you can really do is select to anonymous type like
select new {sp, ps }
Unfortunately there is no way of filtering in included objects. Include is something like all or nothing.
You can read about it:
How to filter nested collection Entity Framework objects?
EF Query With Conditional Include
I've finally made another (hacky) solution. Here is my final code:
using (var context = new BetaalplatformContext())
{
var dienstverleners = context.Dienstverleners.Include(dv => dv.Omgeving)
.Include(dv => dv.Platformen)
.Include(dv => dv.Platformen.Select(pl => pl.Deelnemers))
.Include(dv => dv.Platformen.Select(pl => pl.Deelnemers.Select(dn => dn.Betaalregelingen)))
.Include(dv => dv.Platformen.Select(pl => pl.Deelnemers.Select(dn => dn.Betaalregelingen.Select(br => br.Aanvrager))))
.Include(dv => dv.Platformen.Select(pl => pl.Deelnemers.Select(dn => dn.Betaalregelingen.Select(br => br.Betaler))))
.ToList();
dienstverleners.ForEach(
dv => dv.Platformen.ForEach(
pl => pl.Deelnemers.ForEach(
dn => dn.Betaalregelingen = dn.Betaalregelingen
.Where(br2 => br2.BevestigdOp.HasValue && br2.ExportDatum.HasValue && !br2.StatistiekDatum.HasValue)
.ToList()
)
)
);
return dienstverleners;
}
This way i am abled to keep my models intact (I don't like to use anonymous objects).

Multi Terms search NEST C#

I want to do a search matching multiple values ( an array of values ) like this :
var result1 = _client.Search<type1>(s => s
.Fields(f => f.trip_id)
.Query(q => q
.Terms(t => t.arg1, value1)).Take(_allData))
.Documents.Select(d => d.arg2).ToArray();
var result2 = _client.Search<type2>(s => s
.Query(q => q
.Terms(t => t.arg3, result1))
.Take(_allData)
).Documents.Select(s => s.ar3).ToList();
How can I do ? I was thinking about facets but I don't see how I can do it.
The only way for now that works is with a foreach iterator which is not really effective...
Thanks for your help.
You can express multiple queries like so:
.Query(q=>q.Terms(t=>t.arg3, result1) && q.Terms(t=>t.arg1, value1))
Be sure to read the documentation on writing queries to discover all the good stuff NEST has to offer.
Orelus,
I'd like to use your solution with
.And( af=>af.Term(...), af=>af.Term(...) )
I don't understand where this fits, here's an example of my non-working filter
var results = client.Search<music>(s => s
.Query(q => q
.Filtered(f => f.
Filter(b => b.Bool(m => m.Must(
t => t
.Term(p => p.artist, artist)
&& t.Term(p2 => p2.year, year)
)
)
)
)
)
);

Categories

Resources