Как я могу использовать NEST QueryString и экранировать специальные символы?

Я использую NEST для связи с Elasticsearch в своих приложениях.

В этом случае пользователь вводит в свой поисковый запрос F5503904902, что возвращает правильный результат. Однако, если они ищут запрос F5503904902-90190 или F5503904902-90190_55F, результаты не возвращаются.

Я предположил, что это из-за специальных символов, поэтому я попытался избежать их, но потом тоже никаких результатов не было. Мой запрос правильный, я что-то не так делаю? Кроме того я добавляю подстановочный знак в конец экранированного запроса, чтобы соответствовать любому открытому запросу.

Метод поиска:

public IPagedSearchResult<MyFileObject> Find(ISearchQuery query)
{
    ElasticClient client = ElasticClientManager.GetClient(_indexCluster, ElasticSearchIndexName.MyFileObjects);
    string queryString = EscapeSearchQuery(query.Query) + "*"; 
    var searchResults = client.Search<MyFileObject>(s => s
        .From(query.Skip)
        .Size(query.Take)
        .QueryString(queryString));



    IPagedSearchResult<MyFileObject> pagedSearchResult = new PagedSearchResult<MyFileObject>();
    pagedSearchResult.Results = searchResults.Documents;
    pagedSearchResult.Skip = query.Skip;
    pagedSearchResult.Take = query.Take;
    pagedSearchResult.Total = Convert.ToInt32(searchResults.Total);

    return pagedSearchResult;
}

Метод побега:

private string EscapeSearchQuery(string query)
{
    if (String.IsNullOrWhiteSpace(query)) return query;

    //&& || not handled here
    char[] special = { '+', '-', '=', '>', '<', '!', '(', ')', '{', '}', '[', ']', '^', '\"', '~', '*', '?', ':', '\\', '/', ' ' };
    char[] qArray = query.ToCharArray();

    StringBuilder sb = new StringBuilder();

    foreach (var chr in qArray)
    {
        if (special.Contains(chr))
        {
            sb.Append(String.Format("\\{0}", chr));
        }
        else
        {
            sb.Append(chr);
        }
    }

    return sb.ToString();
}

Я хотел бы получить любую помощь или указатели, почему это не работает, или лучшие способы сделать это.


person Cody    schedule 04.03.2015    source источник


Ответы (1)


В ElasticSearch тире и подчеркивание не являются специальными символами, но они вызывают разделение терминов. Важным является индекс на поле. Я рекомендую настроить мультиполе.

https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/multi-fields.html

Вот пример:

PUT hilden1

PUT hilden1/type1/_mapping
{
  "properties": {
    "multifield1": {
      "type": "string",
      "fields": {
        "raw": {
          "type": "string", 
          "index": "not_analyzed"
        }
      }
    }
  }
}

POST hilden1/type1
{
  "multifield1": "hello"
}

POST hilden1/type1
{
  "multifield1": "hello_underscore"
}

POST hilden1/type1
{
  "multifield1": "hello-dash"
}

Попробуем найти заштрихованное значение:

GET hilden1/type1/_search
{
  "query": {
    "filtered": {
      "filter": {
        "term": {
          "multifield1": "hello-dash"
        }
      }
    }
  }
}

Это не дает никаких результатов, потому что ES за кулисами разбивает поле на две части. Но, поскольку мы настраиваем это поле как составное, мы можем запросить его на основе установленного нами «.raw». Этот запрос даст результаты, которые вы ищете.

GET hilden1/type1/_search
{
  "query": {
    "filtered": {
      "filter": {
        "term": {
          "multifield1.raw": "hello-dash"
        }
      }
    }
  }
}
person jhilden    schedule 04.03.2015