asp.net - Elasticsearch .net客户端嵌套查询容器始终为null

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

尝试通过构建始终为null的querycontainer来动态过滤函数中的结果。我不理解为什么,因为当我调试时,我看到q变量填充在函数中,但是当我检查它的值时,它始终为null。示例代码如下。你知道我做错了什么吗?

谢谢。

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

最佳答案

查询的构造不正确according to the signature of a Term query constructed with the static Query<T> type
Field(Func<T, object>)是一个强类型表达式,用于获取查询应在其上进行操作的字段,并且应使用.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是一个表达式,用于在ProductModel上获取子对象的状态ID;我们使用.First()的事实并不意味着我们要索取第一个状态ID,它只是一个表达式,用于确定如何以简洁的方式访问状态ID。有关更多详细信息,请参见field inference部分。

因为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上的currentStockcount查询),所以the Stock object should be modelled as a nested object使得两个查询的匹配项必须来自同一库存对象。

一旦建模为嵌套对象,查询将变为
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)
                )))
            )
        );
}

与查询json
{
  "bool": {
    "must": [
      {
        "term": {
          "productTypeID": {
            "value": 2
          }
        }
      },
      {
        "nested": {
          "query": {
            "bool": {
              "must": [
                {
                  "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
                                }
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              ]
            }
          },
          "path": "stocks"
        }
      }
    ]
  }
}

关于asp.net - Elasticsearch .net客户端嵌套查询容器始终为null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36676440/

相关文章:

c# - 我如何 TDD 自定义成员(member)提供者和自定义成员(member)用户?

直到刷新页面后才应用 JQUERY Css

asp.net - 如何控制对 ASP.Net MVC 3 View 上的表单字段的访问?

asp.net - 是 SQL 注入(inject)吗?

c# - 当从 javascript 调用时,UpdatePanel 中的 asp.net 按钮会导致 Firefox 15.0.1 中的整个页面刷新

c# - Paypal 快速结帐 Asp.Net

html - 无法使用 MVC 5 在 IE 11 中使用 FontAwesome

elasticsearch - 无法将 Filebeats 与 Elastic Cloud 连接

lucene - ElasticSearch-如何优先考虑来自同一行的匹配

node.js - 如何使用 node.js 删除 Elasticsearch 中的所有索引?