Можно ли добавить пользовательские метаданные в поле Lucene?

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

Это возможно?

Изменить: Хорошо, позвольте мне немного пояснить, приведя пример.

Допустим, у меня есть объект, который я хочу разрешить пользователю помечать пользовательскими тегами, такими как «личный», «любимый», «какой-то проект». Я делаю это, добавляя в документ несколько полей «тег», например:

doc.Add( new Field( "tag", "personal" ) );
doc.Add( new Field( "tag", "favorite" ) );

Проблема в том, что теперь мне нужно записать некоторые метаданные о каждом отдельном теге, в частности, guid, представляющий, откуда взялся этот тег (представьте, что это идентификатор пользователя). У каждого тега потенциально может быть другой guid, поэтому я не могу просто создать поле «tag-guid» (если порядок значений не будет сохранен — см. редактирование 2 ниже). Мне не нужно, чтобы эти метаданные индексировались (и на самом деле я бы предпочел, чтобы этого не было, чтобы избежать попаданий в метаданные), мне просто нужно иметь возможность снова получить их из документа/поля.

doc.GetFields( "tag" )[0].Metadata...

(Здесь я придумываю синтаксис, но надеюсь, что теперь моя точка зрения ясна.)

Редактировать 2: Поскольку это совершенно другой вопрос, я опубликовал новый вопрос для этого подхода: Является ли порядок многозначных полей в Lucene стабильным?

Хорошо, давайте попробуем другой подход... Ключевой проблемной областью является неопределенность значений нескольких полей под одним и тем же именем поля (например, "тег"). Если бы я мог ввести или получить какую-то определенность здесь, я мог бы хранить метаданные в другом поле.

Например, если бы я мог полагаться на то, что порядок значений поля никогда не изменится, я мог бы использовать индекс в наборе значений, чтобы точно определить, на какой тег я ссылаюсь.

Есть ли какая-либо гарантия, что порядок добавления значений в поле останется прежним, когда я извлеку документ позже?


person devios1    schedule 09.02.2011    source источник
comment
не могли бы вы просто добавить его в свой документ: document.Add(new Field(GUID, guidvalue, Field.Store.YES, Field.Index.NO));   -  person Prescott    schedule 09.02.2011
comment
@Prescott проблема в том, что я добавляю несколько значений для одного и того же поля (например, тега), и мне нужно отслеживать определенную информацию о происхождении для каждого тега, поэтому у меня нет возможности просто добавить новое поле для его отслеживания, потому что я могу не идентифицируют их однозначно.   -  person devios1    schedule 09.02.2011
comment
@chaiguy У меня возникли проблемы с полным пониманием того, что вы имеете в виду - не могли бы вы привести очень простой пример?   -  person Prescott    schedule 09.02.2011
comment
@chaiguy Прескотт прав, вы можете добавить несколько полей в документ только для хранения - это обычная практика.   -  person Sergey Mirvoda    schedule 09.02.2011
comment
пытаюсь уточнить здесь: Предположим, следующее определение документа {DocId, Text, Author, CreatedDate}. Вы говорите, что хотели бы также добавить дополнительные данные в отдельные поля. В этом случае предположим, что вы хотите пометить автора с помощью GUID, поэтому добавьте новое поле AuthorGUID для этого документа?   -  person Prescott    schedule 09.02.2011
comment
@chaiguy - Просто любопытно, как вы используете добавление метаданных в метаданные? Интуитивно я бы не подумал о тегах отдельных полей, но документ в целом   -  person Prescott    schedule 09.02.2011
comment
См. обновленный вопрос. Я не могу просто добавить новое поле, потому что поля поддерживают несколько значений, и мне нужны метаданные для каждого значения в одном поле.   -  person devios1    schedule 09.02.2011
comment
Я полагаю, возможно, я мог бы просто как-то добавить его к значению, но не испортит ли это индексацию/поиск? Например, если бы я использовал новое поле (тег, избранное|метаданные)...?   -  person devios1    schedule 09.02.2011
comment
хм, как насчет чего-то вроде нового поля (теги, персональные|дата избранного|дата) с использованием идеи полезной нагрузки Xodarap ниже?   -  person Prescott    schedule 09.02.2011
comment
@chaiguy - да, это было бы, но, используя ссылку Xodarap на полезные нагрузки, вы можете убедиться, что это не так   -  person Prescott    schedule 09.02.2011


Ответы (2)


Это может быть возможно в зависимости от ваших требований к поиску для этого индекса. Таким образом, вы можете контролировать порядок полей. Это потребует обновления обоих полей по мере изменения списка тегов, но накладные расходы могут того стоить.

doc.Add(new Field("tags", "{personal}|{favorite}")); 
doc.Add(new Field("tagsref", "{1234}|{12345}")); 

Примечание. Использование {} позволяет квалифицировать ваш поиск на уникальность там, где существуют похожие значения.

Пример: если бы значения были сохранены как "person|personal|personage", поиск "person" вернул бы документ, в котором есть любой из person, personal или personage. Указав в фигурных скобках, например: «{person}|{personal}|{personage}», я могу искать «{person}» и быть уверенным, что он не даст ложных срабатываний. Конечно, это предполагает, что вы не используете фигурные скобки в своих значениях.

person misteraidan    schedule 24.02.2011
comment
Это то, что я в итоге сделал. Можете ли вы объяснить, что вы подразумеваете под символами {}? Это только для поиска или для хранения полевых данных (как вы делаете)? - person devios1; 25.02.2011
comment
Обновлено с более подробной информацией о фигурных скобках. - person misteraidan; 04.03.2011

Я думаю, вы спрашиваете о полезных нагрузках. .

Изменить: судя по вашему варианту использования, у вас нет желания использовать эти метаданные в своем поиске, вы просто хотите, чтобы они были там. (По сути, вы хотите использовать Lucene в качестве системы базы данных.)

Итак, почему вы не можете использовать бинарное поле?

ExtraData ed = new ExtraData { Tag = "tag", Type = "personal" };
byte[] byteData = BinaryFormatter.Serialize(ed); // this isn't the correct code, but you get the point
doc.Add(new Field("myData", byteData, Field.Store.YES));

Затем вы можете десериализовать его при извлечении.

person Xodarap    schedule 09.02.2011
comment
Это кажется более полезным для взвешивания, для которого его использовал Грант. Я мог видеть, как вы могли бы расширить его, чтобы пометить фрагменты ваших данных, но он кажется более подходящим для специальной обработки внутри самого поля (например, текстовые данные -> текст | 10 данных | 5 - добавление разных весов. В этом случае я думаю он хочет что-то вроде Text Data|GUID — чтобы GUID относился ко всему полю, а не к частям поля, и не ко всему документу - person Prescott; 09.02.2011
comment
Я бегло просмотрел эту страницу, но полезные нагрузки кажутся намного слишком сложными для того, что мне нужно. Похоже, мне придется написать полностью настраиваемый анализатор и вручную генерировать потоки токенов. - person devios1; 09.02.2011
comment
Мне любопытны эти повышения, хотя... можно ли сегментировать строковое значение поля, чтобы я мог прикрепить метаданные и присвоить ему повышение 0, чтобы оно игнорировалось запросами? Поддерживается ли это стандартным анализатором или мне придется использовать другой/написать свой собственный? - person devios1; 09.02.2011
comment
@chaiguy: я отредактировал свой ответ: это больше того, что вы ищете? - person Xodarap; 10.02.2011
comment
Вы правы в том, что у меня нет желания использовать метаданные в поиске, но я хочу иметь возможность использовать значение поля (например, тег) в поиске. Я обновил вопрос с другим подходом. - person devios1; 10.02.2011
comment
@chaiguy: Почему у вас не может быть только одно поле для поиска и одно для этих метаданных? - person Xodarap; 10.02.2011
comment
Я мог бы, если бы я был уверен, что индексы будут совпадать и не изменятся для меня, в соответствии с моим новым подходом. - person devios1; 10.02.2011
comment
@chaiguy: вы можете хранить все, что хотите, в двоичном поле, например. хэш-таблица. Вы можете быть уверены, что это не изменится. - person Xodarap; 10.02.2011