3

嗨,我是弹性嵌套 API 的新手,我正在使用嵌套 5.x。我目前正在开发某种高级搜索页面,因此当用户不检查条件时,我不必在我的查询中包含该过滤器。我正在尝试将 must 运算符下的 2 个查询与使用嵌套的对象初始化方法结合起来。如何实现?我正在关注 [ https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/bool-queries.html]上的示例

var secondSearchResponse = client.Search(new SearchRequest { Query = new TermQuery { Field = Field(p => p.Name), Value = "x" } && new TermQuery { Field = Field(p => p.Name), Value = "y" } });

但它不起作用,因为 Field 类不接受类型参数。

我还尝试从本主题 [ Nest Elastic - Building Dynamic Nested Query中遵循这种方法

这是我的代码

    public HttpResponseMessage GetSearchResult([FromUri] SearchModels queries)
    {
        try
        {
            ///
            string result = string.Empty;
            result += "queryfields + " + queries.queryfields == null ? string.Empty : queries.queryfields;
            result += "datefrom + " + queries.datefrom == null ? string.Empty : queries.datefrom;
            result += "dateto + " + queries.dateto == null ? string.Empty : queries.dateto;
            result += "emitentype + " + queries.emitentype == null ? string.Empty : queries.emitentype;

            QueryContainer andQuery = null;

            //List<QueryContainer> QueryContainers = new List<QueryContainer>();

            IDXNetAnnouncement record = new IDXNetAnnouncement
            {
                kode_emiten = queries.kodeemiten
            };

            #region keyword
            if (!string.IsNullOrEmpty(queries.queryfields))
            {
                var val = queries.queryfields;

                TermQuery tq = new TermQuery
                {
                    Field = queries.queryfields,
                    Value = val
                };

                if (andQuery == null)
                    andQuery = tq;
                else
                    andQuery &= tq;

                //QueryContainers.Add(tq);
            }
            #endregion keyword

            #region kodeemiten
            if (!string.IsNullOrEmpty(queries.kodeemiten))
            {
                var val = queries.kodeemiten;

                TermQuery tq = new TermQuery
                {
                    Name = "kode_emiten",
                    Field = record.kode_emiten,
                    Value = val
                };

                if (andQuery == null)
                    andQuery = tq;
                else
                    andQuery &= tq;

                //QueryContainers.Add(tq);
            }
            #endregion            

            #region date
            if (!string.IsNullOrEmpty(queries.datefrom) && !string.IsNullOrEmpty(queries.dateto))
            {
                DateRangeQuery dq = new DateRangeQuery();
                dq.Name = "tglpengumuman";
                dq.LessThanOrEqualTo = DateMath.Anchored(queries.dateto);
                dq.GreaterThanOrEqualTo = DateMath.Anchored(queries.datefrom);
                dq.Format = "dd/mm/yyyy";

                if (andQuery == null)
                    andQuery = dq;
                else
                    andQuery &= dq;

                //QueryContainers.Add(dq);
            }
            #endregion keyword

            var reqs = (ISearchResponse<IDXNetAnnouncement>)null;

            if (andQuery != null)
            {
                reqs = conn.client.Search<IDXNetAnnouncement>(s => s
                        .AllIndices()
                        .AllTypes()
                        .From(queries.indexfrom)
                        .Size(queries.pagesize)
                        .Query(q => q.Bool(qb => qb.Must(m => m.MatchAll() && andQuery))));
                //var json = conn.client.Serializer.SerializeToString(reqs.ApiCall.ResponseBodyInBytes);
            }
            else
            {
                reqs = conn.client.Search<IDXNetAnnouncement>(s => s
                       .AllIndices()
                       .AllTypes()
                       .From(queries.indexfrom)
                       .Size(queries.pagesize)
                       .Query(m => m.MatchAll()));
            }

            //var reqstring = Encoding.UTF8.GetString(conn.client.);
            var reslts = this.conn.client.Serializer.SerializeToString(reqs,SerializationFormatting.Indented);

            var resp = new HttpResponseMessage()
            {
                Content = new StringContent(reslts)
            };
            resp.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            return resp;
        }
        catch (Exception e)
        {
            var resp = new HttpResponseMessage()
            {
                Content = new StringContent(e.ToString())
            };
            resp.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            return resp;
        }
    }

但这会返回零结果。如何做到这一点?无论如何谢谢。

编辑 :

这是参数变量定义。其搜索关键字的 apoco 模型

public class SearchModels
{
    public string queryfields { get; set; }
    public string datefrom { get; set; }
    public string dateto { get; set; }
    public string emitentype { get; set; }
    public string kodeemiten { get; set; }
    public string issuercode { get; set; }
    public int indexfrom { get; set; }
    public int pagesize { get; set; }

}

IDXNetAnnouncement 是搜索结果的 poco 模型。它实际上是一种存储在弹性服务器上的文档类型

public class IDXNetAnnouncement 
{
    public string perihalpengumuman { get; set; }
    public string attachments { get; set; }
    public string createddate { get; set; }
    public bool efekemiten_spei { get; set; }
    public string jmsxgroupid { get; set; }
    public string tglpengumuman { get; set; }
    public object errordescription { get; set; }
    public string ESversion { get; set; }
    public int oldfinalid { get; set; }
    public bool efekemiten_etf { get; set; }
    public object errorcode { get; set; }
    public string jenisemiten { get; set; }
    public int pkid { get; set; }
    public string judulpengumuman { get; set; }
    public string form_id { get; set; }
    public bool efekemiten_eba { get; set; }
    public string jenispengumuman { get; set; }
    public string nopengumuman { get; set; }
    public string kode_emiten { get; set; }
    public string divisi { get; set; }
    public string EStimestamp { get; set; }
    public bool efekemiten_obligasi { get; set; }
    public long finalid { get; set; }
    public bool efekemiten_saham { get; set; }
    public string kodedivisi { get; set; }
    public string SearchTerms
    {
        get
        {
            return string.Format("{0} {1} {2}", judulpengumuman, kode_emiten, nopengumuman);
        }
    }
}
4

1 回答 1

2

但它不起作用,因为 Field 类不接受类型参数。

您需要确保为ie包含using static 指令Nest.Infer

using static Nest.Infer;

与其余的 using 指令。

.Query(q => q.Bool(qb => qb.Must(m => m.MatchAll() && andQuery))));

无需包装 a Must(),只需执行

.Query(q => q.MatchAll() && andQuery)

这会将两个查询包装在一个bool查询must子句中。您也不需要null检查andQuery,因为 NEST 足够聪明,不会将两个查询组合在一起(如果其中一个或两个都是null.

if (!string.IsNullOrEmpty(queries.queryfields))
{
    var val = queries.queryfields;

    TermQuery tq = new TermQuery
    {
        Field = queries.queryfields,
        Value = val
    };

    if (andQuery == null)
        andQuery = tq;
    else
        andQuery &= tq;

    //QueryContainers.Add(tq);
}

NEST 具有无条件查询的概念,因此您无需检查它queries.queryfields是否为 null 或为空,只需构建查询并将其添加到andQuery. 所以它会变成

var val = queries.queryfields;

andQuery &= new TermQuery
{
    Field = queries.queryfields,
    Value = val
};

在旁边

所有的 NEST 文档都是从源代码生成的;您可以通过单击文档中的任何编辑链接追溯到原始源文件。这将带你到一个 github 页面,例如这个用于 bool 查询的页面。从这里开始,该文档包含一个重要说明,该说明链接回原始来源

于 2017-07-25T10:59:33.220 回答