尝试通过构建始终为null的querycontainer在函数中动态过滤结果。我没有理解为什么因为当我调试时,我看到q变量在函数中被填充但是当我检查它的值时,它总是为空。示例代码如下。你知道我做错了什么吗?
谢谢。
QueryContainer q = null;
if (!ProductType.HasValue || (ProductType.HasValue && ProductType.Value == B2CVariables.PRODUCTTYPE_PRODUCT))
{
q = Query<ProductModel>.Term(t => t.Field(u => u.ProductTypeID == B2CVariables.PRODUCTTYPE_PRODUCT));
q &= Query<ProductModel>.Term(t => t.Field(u => u.Stocks.Any() ? u.Stocks.Any(z => z.StatusID == B2CVariables.STATUS_PRODUCT_ONLINE && (!z.CheckStockStatus || (z.CheckStockStatus && z.CurrentStockCount > 0))) : false));
}
答案 0 :(得分:1)
查询的构造不正确according to the signature of a Term
query constructed with the static Query<T>
type。
Field(Func<T, object>)
是强类型表达式,用于获取查询应在其上运行的字段,并且应使用{{1指定字段必须与字段查询匹配的值 }}。这是一个假设以下设置的示例
.Value(object value)
查询
public static class B2CVariables
{
public const int PRODUCTTYPE_PRODUCT = 2;
public const int STATUS_PRODUCT_ONLINE = 1;
}
public class ProductModel
{
public IList<Stock> Stocks { get; set;}
public int ProductTypeID { get; set;}
}
public class Stock
{
public int StatusID { get; set;}
public bool CheckStockStatus { get; set;}
public int CurrentStockCount { get; set;}
}
if (!ProductType.HasValue || (ProductType.HasValue && ProductType.Value == B2CVariables.PRODUCTTYPE_PRODUCT))
{
q = Query<ProductModel>.Term(t => t
.Field(u => u.ProductTypeID)
.Value(B2CVariables.PRODUCTTYPE_PRODUCT));
q &= Query<ProductModel>.Term(t => t
.Field(u => u.Stocks.First().StatusID)
.Value(B2CVariables.STATUS_PRODUCT_ONLINE)) &&
(Query<ProductModel>.Term(t => t
.Field(u => u.Stocks.First().CheckStockStatus)
.Value(false)) ||
(Query<ProductModel>.Term(t => t
.Field(u => u.Stocks.First().CheckStockStatus)
.Value(true)) &&
Query<ProductModel>.Range(t => t
.Field(u => u.Stocks.First().CurrentStockCount)
.GreaterThan(0))));
}
是表达式,用于获取u.Stocks.First().StatusID
上子对象的状态ID;我们使用ProductModel
的事实并不意味着我们要求第一个状态ID,它只是一个确定如何访问状态ID的表达式简洁的方式。有关详细信息,请参阅field inference部分。
由于.First()
在组合多个查询时可以长时间啰嗦,因此可以使用速记Query<T>.Term(t => t.Field(u => u.Field).Value(value))
代替(它在实践中更短,即使它看起来差不多由于缩进,在这个例子中也一样!)
Query<T>.Term(t => t.Field, value)
两者都产生以下查询
if (!ProductType.HasValue || (ProductType.HasValue && ProductType.Value == B2CVariables.PRODUCTTYPE_PRODUCT))
{
q = Query<ProductModel>.Term(
t => t.ProductTypeID,
B2CVariables.PRODUCTTYPE_PRODUCT);
q &= Query<ProductModel>.Term(
t => t.Stocks.First().StatusID,
B2CVariables.STATUS_PRODUCT_ONLINE) &&
(Query<ProductModel>.Term(
t => t.Stocks.First().CheckStockStatus,
false) ||
(Query<ProductModel>.Term(
t => t.Stocks.First().CheckStockStatus,
true) &&
Query<ProductModel>.Range(t => t
.Field(u => u.Stocks.First().CurrentStockCount)
.GreaterThan(0))));
}
然而,这个查询可能不会做你想要的;因为有一个{
"bool": {
"must": [
{
"term": {
"productTypeID": {
"value": 2
}
}
},
{
"term": {
"stocks.statusID": {
"value": 1
}
}
},
{
"bool": {
"should": [
{
"term": {
"stocks.checkStockStatus": {
"value": false
}
}
},
{
"bool": {
"must": [
{
"term": {
"stocks.checkStockStatus": {
"value": true
}
}
},
{
"range": {
"stocks.currentStockCount": {
"gt": 0.0
}
}
}
]
}
}
]
}
}
]
}
}
查询,它跨子对象组合了两个查询(bool
上的term
查询和checkStockStatus
上的range
,{{3这两个查询的匹配必须来自相同的库存对象。
一旦建模为嵌套对象,查询将变为
currentStockcount
使用查询json
int? ProductType = 2;
QueryContainer q = null;
if (!ProductType.HasValue || (ProductType.HasValue && ProductType.Value == B2CVariables.PRODUCTTYPE_PRODUCT))
{
q = Query<ProductModel>.Term(t => t
.Field(u => u.ProductTypeID)
.Value(B2CVariables.PRODUCTTYPE_PRODUCT));
q &= Query<ProductModel>.Nested(n => n
.Path(u => u.Stocks.First())
.Query(nq => nq
.Term(t => t
.Field(u => u.Stocks.First().StatusID)
.Value(B2CVariables.STATUS_PRODUCT_ONLINE)) &&
(nq.Term(t => t
.Field(u => u.Stocks.First().CheckStockStatus)
.Value(false)) ||
(nq.Term(t => t
.Field(u => u.Stocks.First().CheckStockStatus)
.Value(true)
) && nq.Range(t => t
.Field(u => u.Stocks.First().CurrentStockCount)
.GreaterThan(0)
)))
)
);
}