Поиск по двум документам Lucene

Я использую Lucene.NET в своем проекте. Теперь у меня немного сложное созвездие. У меня есть две сущности:

public class Dash {
  public int Id { get; set; }
  public string Description { get; set; }
  public int ActivityId { get; set; }
  public string Username { get; set; }
}

public class Activity {
  public int Id { get; set; }
  public string Subject { get; set; }
}

Я храню объект Entity как документ и тире как документ в индексе Lucene.

Теперь я могу найти Dash-Entries, например

+Description:"Appointment" +Username:"mm"

или Activity-Entries like

+Subject:"Appointment-Invitation"

Теперь я должен искать Dash-Entries над обоими документами. Например, я должен искать все Dash-записи, которые имеют имя пользователя «mm», а строка «Назначение» в описании или связанная с ним Activity-Entity имеет «Назначение» в теме. В SQL (Pseudo) это будет:

... where Dash.UserName = 'mm' and (Dash.Description like 'Appointment%' or Dash.Activity.Subject like 'Appointment%'

Может кто-нибудь мне помочь, как я могу это сделать с Lucene.NET? Возможно, мне нужно хранить документы по-другому в Lucene.NET-Index?

c#,lucene,full-text-search,lucene.net,

1

Ответов: 1


// Предполагая, что запрос возвращает TopDocs var dashDocs = query "+ dash_username: mm + dash_description: Назначение" сортировать по "dash_ActivityId" var activityDocs = query "+ dash_username: mm + dash_description: Назначение" сортировать по "activity_Id" var dashDocsEnum = dashDocs . ScoreDocs . GetEnumerator () foreach ( var activityDocID в activityDocs . ScoreDocs ) { if ( dashDocsEnum , Current == null ) break ; var activityId = GetId ( activityDocId . td , "activity_id" ); var dashActivityId = GetId ( dashDocsEnum . Current . td , "dash_activityid" ); if ( dashActivityId < activityId ) { // вращать Dash forward, чтобы догнать Activity while ( dashActivityId < activityId ) { if (! dashDocsEnum . MoveNext ()) break ; dashActivityId = GetId ( dashDocsEnum . Current . td , "dash_activityid" ); } } while ( dashActivityId == activityId ) { // в этот момент мы имеем Activity и сопоставленную Dash var fullActivity = GetActivity ( activityDocId . td ); var fullDashActivity = GetDash ( dashDocsEnum . Current . td ); // делаем что-то с Activity и Dash, если (! dashDocsEnum . MoveNext ()) break ; dashActivityId = GetId ( dashDocsEnum . Current . td , "dash_activityid" ); } } = '4263417' itemscope itemtype = 'http: //schema.org/Answer'>
0 принят

вы должны позаботиться о том, чтобы разные типы объектов в одном индексе

Если вы ищете «id: 1», как вы знаете, если вы получили тире или активность?

Или:

  • убедитесь, что имена полей уникальны, т.е. «dash_id», «activity_id»
  • добавьте поле «_type» и добавьте «_type: dash» или «_type: activity» в качестве фильтра для поиска

вы не можете выполнить свое «соединение» в одном запросе, по крайней мере, с текущим Lucene.net (3.0.3)

Lucene - это хранилище документов, это несколько способов хранения хранилища ключей. Каждый документ - «просто куча полей».

Вы можете просто запросить для каждого объекта, а затем использовать Linq для объединения двух коллекций. Но это может быть довольно неэффективным и интенсивным в памяти. Все зависит от того, сколько результатов вы ожидаете. Если число мало, это, вероятно, самое простое.

Однако вы можете сделать что-то достаточно приличное с двумя запросами и «синхронизированным перечислимым». Caveat: Трудно сказать, что такое «Dash», но глядя на свойства, которые я собираюсь предположить, что для каждой операции есть много Dash

Псевдокод

Store.YES

Это было просто списано с моей головы, поэтому извиняюсь, если это не совсем правильно :)

Идея состоит в том, чтобы предвидеть действия, а затем перевести счетчик штриховки вперед, чтобы поддерживать синхронизацию с активностью. Предполагается, что вы сохраняете значения свойств в idполях. Этот подход просто получает idполя, пока мы не найдем совпадение, а затем проецируем весь объект.

Другой вариант

заключается в том, чтобы рассматривать Lucene как «хранилище документов». Создайте класс, который моделирует parent-child. Итак, у Activity есть свойство, которое представляет собой набор Dash.

Сериализуйте этот объект в двоичное поле. Добавьте соответствующие поля для поиска Store.No. Это означает, что соединение не требуется, вы получаете весь объект за один удар.

Это работает, если частота обновления низкая, так как вам нужно обновить весь объект, а не просто добавить одну Dash и полагаться на соединение.

Удачи :)

C #, Lucene, полнотекстовой поиск, lucene.net,
Похожие вопросы