В Lucene.Net как выполнять поиск по свойству дочернего объектаC#

Место общения программистов C#
Ответить
Anonymous
 В Lucene.Net как выполнять поиск по свойству дочернего объекта

Сообщение Anonymous »

У меня есть следующая структура/код, в котором я пытаюсь исправить одну проблему. С самого начала это можно было сделать по-другому, но это то, что есть.
При поиске всех сотрудников по идентификатору отдела сотрудники должны быть возвращены в поиске с порядком ASC тег, за исключением случаев, когда тег имеет значение null, что должно отправить его в конец поиска.
это связь структуры



Сотрудник
Идентификатор отдела
Название отдела
Тег




Сэм
101
Бухгалтерский учет
"ааа"


Сэм
102
Доставка
Null


Тим
101
Бухгалтерский учет
"эээ"


Тим
102
Доставка
"ззз"



и представление json:

Код: Выделить всё

{
"Name": "Sam",
"Departments": [
{
"ID": 101,
"Name": "Accounting",
"Tag": "aaa"
},
{
"ID": 102,
"Name": "Shipping",
"Tag": Null
},
]
},
{
"Name": "Tim",
"Departments" : [
{
"ID": 101,
"Name": "Accounting",
"Tag": "eee"
},
{
"ID": 102,
"Name": "Shipping",
"Tag": "zzz"
},
]
}
Итак, если я ищу всех сотрудников, принадлежащих к бухгалтерии (101), поскольку у Сэма есть значение tagNumber "aaa", и оно предшествует тегу Тима, чей тег: " эээ», то Сэм должен вернуться первым.
Но если мы ищем отдел доставки (102), тэг Сэма в этом отделе равен нулю; и у Тима есть значение тега для этого отдела, то Тим должен появиться первым.

Код: Выделить всё

When searching by Accounting ID (101) ASC --> Tag number determines order (aaa is before eee)
Sam
Tim
When searching by Shipping ID (102) ASC --> Tag number Null goes to bottom.  zzz has precedence over null and therfore, Tim should show up first
Tim
Sam
Вот как сейчас создаются документы и поля:

Код: Выделить всё

var doc = new Document();
doc.Add(new Field("Name", "Sam", fieldStored));
doc.Add(new Field("Department.Id1", 101, fieldStored));
doc.Add(new Field("Department.Name1", "Accounting", fieldStored));
doc.Add(new Field("Department.Tag1", "aaa", fieldStored));
doc.Add(new Field("Department.Id2", 102, fieldStored));
doc.Add(new Field("Department.Name2", "Shipping", fieldStored));
doc.Add(new Field("Department.Tag2", null, fieldStored));

var doc = new Document();
doc.Add(new Field("Name", "Tim", fieldStored));
doc.Add(new Field("Department.Id1", 101, fieldStored));
doc.Add(new Field("Department.Name1", "Accounting", fieldStored));
doc.Add(new Field("Department.Tag1", "eee", fieldStored));
doc.Add(new Field("Department.Id2", 102, fieldStored));
doc.Add(new Field("Department.Name2", "Shipping", fieldStored));
doc.Add(new Field("Department.Tag2", "zzz", fieldStored));
Мой поиск в классе TagComparer выполняется следующим образом

Код: Выделить всё

public class TagComparator : FieldComparer
{
private readonly BytesRef[] bvalues;
..........................
public override FieldComparer SetNextReader(AtomicReaderContext context)
{
sortedResults = FieldCache.DEFAULT.GetTermsIndex(context.AtomicReader, field);
return this;
}

public override void Copy(int slot, int doc)
{
termCopy = new BytesRef();
sortedResults.Get(doc, termCopy);
bvalues[slot] = termCopy;
}
}
СВОДКА ПРОБЛЕМЫ:
В данный момент он возвращает «Сэм» перед Тимом для отдела доставки (102), хотя номер тега Сэма равен нулю и « Тим" позже, хотя у него есть значение тега для этого отдела "zzz".
МОЯ ПОПЫТКА:
Поскольку на моих серверах выделено много ресурсов , я могу немного пожертвовать скоростью поиска, добавив больше кода в метод переопределения копирования. Решение будет означать:
  • сохраните идентификатор отдела до того, как код поиска возьмет на себя управление
  • Метод копирования будет выполняться один раз для каждого обращения пользователя, принадлежащего к этому отделу.
  • получить весь документ хит, который показывает идентификатор отдела и значение номера тега
  • если номер тега имеет допустимое значение, он отображается нормально, если нет, он отображается внизу

    Код: Выделить всё

         for (int i = 0; i < wholeDoc.GetValues("Department.Id").Length; i++)
    {
    if(int.Parse(wholeDoc.GetValues("Department.Id")[i]) == 1234) // department Id
    {
    string tagNumber= wholeDoc.GetValues("TagNumber")[i];
    if (string.IsNullOrWhiteSpace(tagNumber))
    SetBottom(doc);
    else
    bvalues[slot] = new BytesRef(wholeDoc.GetValues("TagNumber")[i]);
    break;
    }
    }
    
Это решение работает, но проблема в том, что оно значительно замедляет поиск из-за добавленной мной логики. Должен быть способ позволить искателю выполнить всю работу. Как мне сообщить поисковику о необходимости сортировки на основе тега, если он имеет значение, а не нет, исходя из моей структуры данных? Или необходимо создать документ между Сэмом и ID1 и целый отдельный документ для Сэма и ID2 и так далее с Тимом?

Подробнее здесь: https://stackoverflow.com/questions/787 ... ild-object
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»