Реляционная база данных индекса гнезда elasticsearch

Я проиндексировал 2 отдельные таблицы в Elasticsearch — Meetings и MeetingAttendees. Связь «один ко многим» — на собрании может быть много участников.

Идентификатор встреч
: 1

ID: 2

Участники собрания
MeetingAttendeeID: 1
MeetingID: 1
Имя: "tom"

MeetingAttendeeID: 2
MeetingID: 1
Имя: "david"

MeetingAttendeeID: 3
MeetingID: 2
Имя: "david"

Я пытался создать такие отношения, но я не вижу никакой разницы в ES.

client.CreateIndex(ci => ci.Index("testmappingindex")
                .AddMapping<Meeting>(m => m.MapFromAttributes())
                .AddMapping<MeetingAttendee>(m => m.MapFromAttributes().SetParent<Meeting>()));

Я хотел бы иметь возможность запрашивать так:

result = client.Search<Meeting>(s => s
                .Type("Meeting")
                .From(0)
                .Size(10)
                .Query(q => q.MeetingAttendees(ma => ma.Terms(t => t.Name == "david")))
                    )
            ).Documents.ToList();

Однако сопоставление не работает, я не вижу никаких запросов, исходящих от скрипача, и я не уверен, что этот запрос вернет встречи с Дэвидом в качестве участника.


person user3754124    schedule 29.05.2015    source источник


Ответы (1)


Я рекомендую вам обрабатывать вложенный объект. отношения между Meeting и Attendee. Это означает, что мы будем хранить все данные в одном документе (совещании).

Классы для встреч и посещения:

public class Meeting
{
    public int Id { get; set; }
    public string Name { get; set; }
    [ElasticProperty(Type = FieldType.Nested)]
    public List<Attendee> MeetingAttendees { get; set; }
}

public class Attendee
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Создать индекс:

var indicesOperationResponse = client.CreateIndex(descriptor => descriptor
    .Index(indexName)
    .AddMapping<Meeting>(m => m.MapFromAttributes()));

Проиндексируйте некоторые данные:

var david = new Attendee {Id = 1, Name = "David"};
var carl = new Attendee {Id = 2, Name = "Carl"};
var jason = new Attendee {Id = 3, Name = "Jason"};

client.Index(new Meeting {Id = 1, Name = "Meeting1", MeetingAttendees = new List<Attendee>{david, carl}});
client.Index(new Meeting {Id = 2, Name = "Meeting2", MeetingAttendees = new List<Attendee>{jason}});
client.Index(new Meeting {Id = 3, Name = "Meeting3", MeetingAttendees = new List<Attendee>{jason, david}});

client.Refresh();

Мы должны немного изменить ваш запрос:

var result = client.Search<Meeting>(s => s
    .From(0)
    .Size(10)
    .Query(q => q.Nested(n => n
        .Path(p => p.MeetingAttendees.First())
        .Query(qq => qq
            .Term(meeting => meeting.OnField(f => f.MeetingAttendees.First().Name).Value("david"))))));

Результат эластичного поиска:

{
   "took": 4,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 2,
      "max_score": 1.4054651,
      "hits": [
         {
            "_index": "my_index",
            "_type": "meeting",
            "_id": "1",
            "_score": 1.4054651,
            "_source": {
               "id": 1,
               "name": "Meeting1",
               "meetingAttendees": [
                  {
                     "id": 1,
                     "name": "David"
                  },
                  {
                     "id": 2,
                     "name": "Carl"
                  }
               ]
            }
         },
         {
            "_index": "my_index",
            "_type": "meeting",
            "_id": "3",
            "_score": 1.4054651,
            "_source": {
               "id": 3,
               "name": "Meeting3",
               "meetingAttendees": [
                  {
                     "id": 3,
                     "name": "Jason"
                  },
                  {
                     "id": 1,
                     "name": "David"
                  }
               ]
            }
         }
      ]
   }
}

ОБНОВЛЕНИЕ:

В вашем случае, когда вы собираетесь индексировать больше связанных данных, стоит взглянуть на отношение родитель-потомок

Примеры классов:

public class Meeting
{
    public int Id { get; set; }
    public string Name { get; set; } 
}

public class Attendee
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Отображение:

var indicesOperationResponse = client.CreateIndex(descriptor => descriptor
    .Index(indexName)
    .AddMapping<Meeting>(m => m.MapFromAttributes())
    .AddMapping<Attendee>(m => m.MapFromAttributes().SetParent<Meeting>()));

Образец данных:

var david = new Attendee { Id = 1, Name = "David"};
var carl = new Attendee { Id = 2, Name = "Carl"};
var jason = new Attendee {Id = 3, Name = "Jason"};

client.Index(new Meeting {Id = 1, Name = "Meeting1"});
client.Index(new Meeting {Id = 2, Name = "Meeting2"});
client.Index(new Meeting {Id = 3, Name = "Meeting3"});

client.Index(david, descriptor => descriptor.Parent("1"));
client.Index(carl, descriptor => descriptor.Parent("1"));
client.Index(jason, descriptor => descriptor.Parent("2"));

client.Refresh();

Теперь нам нужно найти родителя по его дети. С NEST вы можете сделать это с помощью этого запроса:

var searchResponse = client.Search<Meeting>(s => s
    .Query(q => q
        .HasChild<Attendee>(c => c
            .Query(query => query.Term(t => t.OnField(f => f.Name).Value("david"))))));
person Rob    schedule 30.05.2015
comment
Почему вложенные объекты? Что делать, если я хочу запросить только участников собрания? Я планирую расширить это на множество разных таблиц, таких как таблица пользователей, внешний ключ которой примерно на 20 других таблиц, включая таблицу участников собрания. - person user3754124; 01.06.2015
comment
@ user3754124 Я рассмотрел ваш комментарий и обновил свой ответ. - person Rob; 01.06.2015