Хранение перколятора в отдельном индексе, когда возможно только одно отображение на индекс? - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть 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 Ответ

0 голосов
/ 29 декабря 2018

Полагаю, это означает, что я должен описать отображение 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 вы всегда можете нажать кнопку редактирования на странице документов, чтобы получить ссылку на исходный источник, из которого она сгенерирована:

Edit docs link

и

Original source code

, что приводит к https://github.com/elastic/elasticsearch-net/blob/6.x/src/Tests/Tests/QueryDsl/Specialized/Percolate/PercolateQueryUsageTests.cs в случае документации Percolate 6.x.

...