Динамический запрос с упругим поиском с помощью инициализатора объектов NEST 5.x
Привет, я новичок в API эластичных гнезд и использую гнездо 5.x. В настоящее время я разрабатываю какую-то страницу расширенного поиска, поэтому, когда пользователь не проверяет критерии, мне не нужно включать этот фильтр в мой запрос. Я пытаюсь объединить 2 запроса под оператором must с подходом инициализатора объекта, используя гнездо. Как этого добиться? Я следую примеру на [ https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/bool-queries.html]
var secondSearchResponse = client.Search (новый SearchRequest { Query = новый TermQuery { Field = Field(p => p.Name), Value = "x" } && new TermQuery { Field = Field(p => p.Name), Value = "y" } });
Но это не работает, потому что класс Field не принимает аргументы типа.
Я также пытался следовать этому подходу из этой темы [ Nest Elastic - Построение динамического вложенного запроса
вот мой код
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; } }
Но это возвращает нулевой результат. Как этого добиться? В любом случае, спасибо.
РЕДАКТИРОВАТЬ:
Это определение переменной params. Его апоко модель поиска по ключевым словам
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 - это модель результатов поиска. На самом деле это тип документа, который хранится на эластичном сервере.
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); } } }
1 ответ
Но это не работает, потому что класс Field не принимает аргументы типа.
Вы должны убедиться, что вы используете статическую директиву Nest.Infer
т.е.
using static Nest.Infer;
с остальными директивами использования.
.Query (q => q.Bool (qb => qb.Must (m => m.MatchAll () && andQuery))));
Не нужно завернуть в 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
является нулевым или пустым, просто создайте запрос и добавьте его в andQuery
, Так бы и стало
var val = queries.queryfields;
andQuery &= new TermQuery
{
Field = queries.queryfields,
Value = val
};
В сторону
Вся документация NEST генерируется из исходного кода; Вы можете вернуться к исходному файлу, нажав на любую ссылку редактирования в документации. Это приведет вас к странице GitHub, такой как эта для запросов bool. Отсюда, документ содержит важную заметку, которая ссылается на первоисточник.