Использование MinimumShouldMatch с запросом терминов в asticsearch
Я пишу запрос в гнезде для эластичного поиска, который соответствует списку стран - он совпадает по времени, когда какая-либо из стран в списке присутствует в ESCountryDescription (список стран). Я хочу совпадать только тогда, когда все страны в CountryList соответствуют ESCountryDescription. Я считаю, что мне нужно использовать MinimumShouldMatch, как в этом примере http://www.elastic.co/guide/en/elasticsearch/reference/0.90/query-dsl-terms-query.html
a.Terms(t => t.ESCountryDescription, CountryList)
Но я не могу найти способ добавления MinimumShouldMatch в мой запрос выше.
2 ответа
Вы можете подать заявку MinimumShouldMatch
патаметер в TermsDescriptor
, Вот пример:
var lookingFor = new List<string> { "netherlands", "poland" };
var searchResponse = client.Search<IndexElement>(s => s
.Query(q => q
.TermsDescriptor(t => t.OnField(f => f.Countries).MinimumShouldMatch("100%").Terms(lookingFor))));
или же
var lookingFor = new List<string> { "netherlands", "poland" };
var searchResponse = client.Search<IndexElement>(s => s
.Query(q => q
.TermsDescriptor(t => t.OnField(f => f.Countries).MinimumShouldMatch(lookingFor.Count).Terms(lookingFor))));
И это весь пример
class Program
{
public class IndexElement
{
public int Id { get; set; }
[ElasticProperty(Index = FieldIndexOption.NotAnalyzed)]
public List<string> Countries { get; set; }
}
static void Main(string[] args)
{
var indexName = "sampleindex";
var uri = new Uri("http://localhost:9200");
var settings = new ConnectionSettings(uri).SetDefaultIndex(indexName).EnableTrace(true);
var client = new ElasticClient(settings);
client.DeleteIndex(indexName);
client.CreateIndex(
descriptor =>
descriptor.Index(indexName)
.AddMapping<IndexElement>(
m => m.MapFromAttributes()));
client.Index(new IndexElement {Id = 1, Countries = new List<string> {"poland", "germany", "france"}});
client.Index(new IndexElement {Id = 2, Countries = new List<string> {"poland", "france"}});
client.Index(new IndexElement {Id = 3, Countries = new List<string> {"netherlands"}});
client.Refresh();
var lookingFor = new List<string> { "germany" };
var searchResponse = client.Search<IndexElement>(s => s
.Query(q => q
.TermsDescriptor(t => t.OnField(f => f.Countries).MinimumShouldMatch("100%").Terms(lookingFor))));
}
}
Относительно вашей проблемы
- Для условий: "Нидерланды" вы получите документ с Id 3
- Для терминов: "Польша" и "Франция" вы получите документы с Id 1 и 2
- Для терминов: "Германия" вы получите документ с Id 1
- Для терминов: "Польша", "Франция" и "Германия" вы получите документ с Id 1
Я надеюсь, что это ваша точка зрения.
Вместо того чтобы делать
.Query(q => q
.Terms(t => t.ESCountryDescription, CountryList))
Вы можете использовать команду ниже
.Query(q => q
.TermsDescriptor(td => td
.OnField(t => t.ESCountryDescription)
.MinimumShouldMatch(x)
.Terms(CountryList)))
Посмотрите это для модульных тестов в GitHub-репозитории asticsearch-net.