我必须编写一个查询,如果我的对象有 parking 位,则必须返回该查询。在索引中, parking 位以整数形式存储,以指示该对象有多少个 parking 位。在查询中,该属性为boolean,以指示我们是否要搜索对象是否具有 parking 位。
我尝试使用条件查询来执行此操作,但是正如我现在所看到的,这是错误的方式。
我的问题是,如何编写HasParking()
函数,在这里我可以检查字段值是否大于0,这表明该对象具有 parking 位。
这是我开始的方式:
public partial class ElasticSearchService
{
private List<Func<QueryContainerDescriptor<AdvertisementObjectEntityExtended>, QueryContainer>> filters = null;
public async Task<List<AdvertisementObjectEntityExtended>> AdvancedSearchAsync(AdvancedFilter filter)
{
filters = new List<Func<QueryContainerDescriptor<AdvertisementObjectEntityExtended>, QueryContainer>>();
string location = !string.IsNullOrEmpty(filter.LocationSuggestion.SubLocation) ? filter.LocationSuggestion.SubLocation : filter.LocationSuggestion.City;
HasOrientation(filter.Orientations);
HasStructure(filter.Structures);
HasHeatingType(filter.HeatingTypes);
HasDescription(filter.ObjectDescriptions);
HasPropertyCondition(filter.PropertyConditions);
HasBelongingSurface(filter.BelongingSurfaces);
ISearchResponse<AdvertisementObjectEntityExtended> result = await Client.SearchAsync<AdvertisementObjectEntityExtended>(s => s
.Index(ElasticClientFactorySettings.AdvertisementObjectIndex)
.Query(q =>
q.QueryString(qs => qs.DefaultField(f => f.Location.ToLower()).Query($"{location.ToLower()}")) &&
q.MatchPhrase(x => x.Field(t => t.SubCategoryKey).Query(filter.Subcategory.Key)) &&
q.Term(t => t.IsRentable, filter.IsRentable) &&
q.Term(t => t.Garage, filter.Garage) &&
q.Term(t => t.WiFi, filter.WiFi) &&
q.Term(t => t.Elevator, filter.Elevator) &&
q.Term(t => t.FurnishState, filter.FurnishState) &&
q.Term(t => t.Deposit, filter.Deposit) &&
q.Term(t => t.Duplex, filter.Duplex) &&
q.Term(t => t.SeparateKitchen, filter.SeparateKitchen) &&
q.Term(t => t.LaundryAndDryingRoom, filter.LaundryAndDryingRoom) &&
q.Term(t => t.Basement, filter.Basement) &&
q.Term(t => t.Terrace, filter.Terrace) &&
q.Term(t => t.Balcony, filter.Balcony) &&
q.Term(t => t.Loggia, filter.Loggia) &&
q.Term(t => t.FrenchBalcony, filter.FrenchBalcony) &&
q.Term(t => t.EnergyPassport, filter.EnergyPassport) &&
q.Term(t => t.ImmediatelyHabitable, filter.ImmediatelyHabitable) &&
q.Term(t => t.VATRefount, filter.VATRefount) &&
q.Term(t => t.ExchangePossible, filter.ExchangePossible) &&
q.Term(t => t.Filed, filter.Filed) &&
q.Term(t => t.Mortgaged, filter.Mortgaged) &&
q.Term(t => t.Longue, filter.Longue) &&
q.Term(t => t.Wardrobe, filter.Wardrobe) &&
q.Term(t => t.Penthouse, filter.Penthouse) &&
q.Term(t => t.WarmWater, filter.WarmWater) &&
q.Term(t => t.Intercom, filter.Intercom) &&
q.Term(t => t.Climate, filter.Climate) &&
q.Term(t => t.Phone, filter.Phone) &&
q.Term(t => t.Alarm, filter.Alarm) &&
q.Term(t => t.Security, filter.Security) &&
q.Term(t => t.SecurityDoor, filter.SecurityDoor) &&
q.Term(t => t.VideosSurveillance, filter.VideosSurveillance) &&
q.Term(t => t.CableTV, filter.CableTV) &&
q.Term(t => t.Fireplace, filter.Fireplace) &&
q.Term(t => t.BestDeal, filter.IsBestDeal) &&
q.Range(r => r.Field(f => f.Price)
.GreaterThanOrEquals(filter.PriceFrom)
.LessThanOrEquals(filter.PriceTo)) &&
q.Range(r => r.Field(f => f.Quadrature)
.GreaterThanOrEquals(filter.QuadratureFrom)
.LessThanOrEquals(filter.QuadratureTo)) &&
q.Range(r => r.Field(f => f.Badrooms)
.GreaterThanOrEquals(filter.BadroomsFrom)
.LessThanOrEquals(filter.BadroomsTo)) &&
q.Bool(bq => bq.Filter(filters)))
.Sort(s =>
s.Field(f => SortByFilter(f, filter.Sort))));
return result.Documents.ToList();
}
private QueryBase HasParking(bool value)
{
return !value ?
null :
+new TermQuery
{
Field = Infer.Field<AdvertisementObjectEntityExtended>(f => f.Parking),
Value = 1
};
}
private QueryBase HasShowcase3D()
{
throw new NotImplementedException();
}
private QueryBase HasImages()
{
throw new NotImplementedException();
}
private QueryBase HasVideoURL()
{
throw new NotImplementedException();
}
private void HasOrientation(AdvertisementObjectOrientation[] orientations)
{
if (orientations != null && orientations.Any())
{
filters.Add(fq => fq.Terms(t => t.Field(f => f.Orientation).Terms(orientations)));
}
}
private void HasStructure(AdvertisementObjectStructure[] structures)
{
if (structures != null && structures.Any())
{
filters.Add(fq => fq.Terms(t => t.Field(f => f.Structure).Terms(structures)));
}
}
private void HasHeatingType(AdvertisementObjectHeating[] heatingTypes)
{
if (heatingTypes != null && heatingTypes.Any())
{
filters.Add(fq => fq.Terms(t => t.Field(f => f.HeatingType).Terms(heatingTypes)));
}
}
private void HasDescription(AdvertisementObjectDescription[] descriptions)
{
if (descriptions != null && descriptions.Any())
{
filters.Add(fq => fq.Terms(t => t.Field(f => f.ObjectDescription).Terms(descriptions)));
}
}
private void HasPropertyCondition(AdvertisementObjectPropertyCondition[] propertyConditions)
{
if (propertyConditions != null && propertyConditions.Any())
{
filters.Add(fq => fq.Terms(t => t.Field(f => f.PropertyCondition).Terms(propertyConditions)));
}
}
private void HasBelongingSurface(AdvertisementObjectBelongingSurfaces[] belongingSurfaces)
{
if (belongingSurfaces != null && belongingSurfaces.Any())
{
filters.Add(fq => fq.Terms(t => t.Field(f => f.BelongingSurfaces).Terms(belongingSurfaces)));
}
}
}
最佳答案
您可以有一个这样的方法,该方法返回NumericRangeQuery
private NumericRangeQuery HasParking(bool value)
{
if(value)
{
return new NumericRangeQuery
{
Name = "named_query",
Boost = 1.1, // Remove the boost if you do not need it
Field = "parking",
GreaterThan = 0
};
}
return null;
}
现在,将此方法挂接到您的过滤器链中,因为这将返回一个NumericRangeQuery
对象。应该从我们要根据要传递给此方法的boolean
字段添加范围查询的位置调用此方法,因此有条件地将其添加到NEST客户端生成的查询中。您可以通过类似于以下内容的调用来挂钩此查询
q.Range(r => HasParking(<param>));
关于c# - 不同类型的C#NEST条件过滤器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63290775/