6

I am working on a project that relies on Lucene.NET. Up to this point, I have had a class that had simple name/value properties (like int ID { get; set; }). However, I now need to add a new property to my index. The property is a type of List. Up to this point, I've updated my index like so...

MyResult result = GetResult();
using (IndexWriter indexWriter = Initialize())
{
  var document = new Document();
  document.Add(new Field("ID", result.ID.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZE));
  indexWriter.AddDocument(document); 
}

Now, MyResult has a property that represents a List. How do I put that in my index? The reason I need to add it to my index is so that I can get it back out later.

Eels Fan
  • 2,043
  • 6
  • 22
  • 23
  • Have you considered using something that stores schemaless, unstructured documents instead of just key-value pairs? This would solve your problem (some examples, RavenDB, elasticsearch, MongoDB). Otherwise, you have would have to generate a notation for the key that contains array information as well as nested property information (easy enough, but a PITA and as noted above, there are things that do this already). – casperOne Apr 03 '13 at 17:04
  • What does your list contain? Does it need to be searchable? – Jf Beaulac Apr 03 '13 at 18:40
  • The list does NOT need to be searchable. – Eels Fan Apr 04 '13 at 12:17

1 Answers1

7

You can add each value in the list as a new field with the same name (lucene supports that) and later read those values back into a string list:

MyResult result = GetResult();
using (IndexWriter indexWriter = Initialize())
{
    var document = new Document();
    document.Add(new Field("ID", result.ID.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZE));

    foreach (string item in result.MyList)
    {
         document.Add(new Field("mylist", item, Field.Store.YES, Field.Index.NO));
    }

    indexWriter.AddDocument(document);
}

Here's how to extract the values from a search result:

MyResult result = GetResult();
result.MyList = new List<string>();

foreach (IFieldable field in doc.GetFields())
{
    if (field.Name == "ID")
    {
        result.ID = int.Parse(field.StringValue);
    }
    else if (field.Name == "myList")
    {
        result.MyList.Add(field.StringValue);
    }
}
Oliver
  • 9,239
  • 9
  • 69
  • 100
Omri
  • 887
  • 8
  • 24
  • 2
    +1, best way to do it. But the field should be created with Field.Index.NO since asker specified it does not need to be searchable. – Jf Beaulac Apr 04 '13 at 18:22