Хранение перколятора в отдельном индексе, когда возможно только одно отображение на индекс?
У меня есть SearchAgent
документ в индексе под названием searchagent
который выглядит так:
[ElasticsearchType(IdProperty = "Id")]
public class SearchAgent
{
public string Id { get; set; }
[Keyword]
public string UserId { get; set; }
public QueryContainer Query { get; set; }
}
Это потому, что я хочу, чтобы мои пользователи создавали "поисковые агенты", которые будут уведомлять пользователя, когда будет вставлен новый документ для определенного поиска.
Теперь документ, для которого я хочу найти соответствующий поисковый агент, находится в items
индекс и является Item
, Это выглядит следующим образом:
[ElasticsearchType(IdProperty = "Id")]
public class Item
{
public string Id { get; set; }
public string Title { get; set; }
}
Это также, кажется, то, что рекомендует документация:
Учитывая дизайн перколяции, часто имеет смысл использовать отдельные индексы для перколятных запросов и перколируемых документов, в отличие от одного индекса...
Однако сейчас я не могу проиндексировать документы поискового агента, так как их Query
относится к собственности на Item
документ. И это приводит к следующей ошибке:
Невозможно найти сопоставление полей для поля с именем [title]
Я думаю, это означает, что я должен описать Item
а также SearchAgent
картирование в searchagent
индекс.
Но в Elasticsearch 6 они убрали поддержку нескольких сопоставлений на индекс, поэтому это невозможно.
Как я могу обойти эту проблему?
1 ответ
Я думаю, это означает, что я должен описать
Item
а такжеSearchAgent
картирование вsearchagent
индекс.
Это правильно для 6.x. По сути, перколяция должна знать о сопоставлении документов, которые будут перколироваться, поэтому в индексе, содержащем запросы, также должны быть поля для документов, которые будут перколироваться.
В NEST 6.x это можно сделать с
var client = new ElasticClient();
var createIndexResponse = client.CreateIndex("percolation", c => c
.Mappings(m => m
.Map<SearchAgent>(mm => mm
.AutoMap<SearchAgent>()
.AutoMap<Item>()
)
)
);
Это позволит автоматизировать свойства обоих SearchAgent
а также Item
под отображением для SearchAgent
и приведет к следующему запросу
PUT http://localhost:9200/percolation?pretty=true
{
"mappings": {
"searchagent": {
"properties": {
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"userId": {
"type": "keyword"
},
"query": {
"type": "percolator"
}
}
}
}
}
Обратите внимание, что свойство с одним и тем же именем в обоих POCO будет отображать последнее свойство этого имени для сопоставления, поэтому рекомендуется, чтобы свойства имели такое же отображение или еще лучше, чтобы документы запроса содержали свойства с разными именами (Id
Это хорошо, если они оба отображаются одинаково), чтобы избежать путаницы в будущем.
С настроенным индексом перколяции таргетинг документов в другом индексе теперь будет достигаться с помощью
var searchResponse = client.Search<SearchAgent>(s => s
.Index("percolation") // index containing queries
.Query(q => q
.Percolate(p => p
.Type<Item>()
.Index("items") // index containing documents
.Id("item-id") // document id
.Field(f => f.Query) // field on SearchAgent containing query
)
)
);
который выполняет следующий запрос
POST http://localhost:9200/percolation/searchagent/_search
{
"query": {
"percolate": {
"field": "query",
"id": "item-id",
"index": "items",
"type": "item"
}
}
}
Вы можете также создать соглашения для POCO на ConnectionSettings
var defaultIndex = "default-index";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex)
.DefaultMappingFor<SearchAgent>(d => d
.IndexName("percolation")
)
.DefaultMappingFor<Item>(d => d
.IndexName("items")
);
var client = new ElasticClient(settings);
Тогда поисковый запрос можно использовать
var searchResponse = client.Search<SearchAgent>(s => s
.Query(q => q
.Percolate(p => p
.Type<Item>()
.Index<Item>()
.Id("item-id")
.Field(f => f.Query)
)
)
);
Наконец, взгляните на документацию NEST Percolation Query DSL; это определенно может быть сделано с улучшением, так как пропускает некоторую информацию, которая не включается, когда она автоматически генерируется из набора тестов, но, надеюсь, это даст вам представление. С любой документацией NEST вы всегда можете нажать кнопку редактирования на странице документов, чтобы получить ссылку на исходный источник, из которого она сгенерирована:
а также
что приводит к https://github.com/elastic/elasticsearch-net/blob/6.x/src/Tests/Tests/QueryDsl/Specialized/Percolate/PercolateQueryUsageTests.cs в случае документации Percolate 6.x.