Elasticsearch .net客户端Nest querycontainer始终为null

时间:2016-04-17 12:24:51

标签: asp.net asp.net-mvc elasticsearch nest

尝试通过构建始终为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));
        }

1 个答案:

答案 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)
                )))
            )
        );
}