How to create an index based on arrays in C# SDK?

Hi,

I am converting a CBLite 1.4 app to version 2.7. This involves converting the Map/Reduce views into indexes and queries. One of the MapDelegate functions creates multiple indexes based on an array within a document. Could someone explain how to do this in CBLite 2.7, using the C# SDK?

    public override MapDelegate Map
    {
        get
        {
            return (document, emit) =>
            {

                dynamic documentType;
                document.TryGetValue("documentType", out documentType);


                switch (documentType as string)
                {
                    case "look":
                        {
                            dynamic items;
                            document.TryGetValue("items", out items);
                            if (items is JArray)
                            {
                                foreach (var item in items)
                                {
                                    string divisionCode = item.divisionCode;
                                    string styleSeasonCode = item.styleSeasonCode;
                                    int id = item.id;

                                    emit(string.Format("{0}_{1}_{2}",
                                        divisionCode,
                                        styleSeasonCode,
                                        id
                                        ), item);
                                }
                            }
                            break;
                        }
                    default:
                        break;
                }
            };
        }
    }

As part of the upgrade to 2.7, I added a method called GetIndex, but it does not have a reference to a document.

It seems like each time a “look” document is saved, I need to create a new Index based on the items array of that document. Is this possible/practical? How else can I do it? Can we avoid changing the document structure?

I think you are misunderstanding what indexes actually are. They are not the same in any way as they were in 1.x. They are exactly equivalent to SQL indexes now. All they do is speed up queries, but they are not required to run queries. Queries have no prerequisites at all. They can be run completely ad-hoc. Try to think as if you were writing a SQL query…what information would you want to extract from the document?

Ah, ok - for now I can implement the query without the index.

Let’s say I implement the query, and then I find it needs the index for performance reasons. Is it possible to create the index based on these inner array properties, like in the 1.4 version?

I think it might make more sense to move the “items” array into separate documents. Each document would have properties for DivisionCode, StyleSeasonCode, and Id, with indexes on those properties. The downside of this is that I’d need a migration script. Do you agree this is the right approach, if it’s too slow without the index?

You will need to stop trying to compare things to 1.x since they do not have the same purpose. You don’t actually create indexes in the form that they are now at all in 1.x. You can probably create an index on the array property itself (I’m not an expert in how the indexes work).

The second approach you mention, splitting the items into separate documents, is definitely more in line with NoSQL style and more horizontally scalable though.