Indexes: Dynamic Index Fields


Indexing documents fields KEYS

Example - index any field under object

The following example allows you to:

  • Index any field that is under the some object from the document.
  • After index is deployed, any new field added to the this object will be indexed as well.

  • The document:

    class Product:
        def __init__(self, Id: str = None, attributes: Dict[str, object] = None):
            self.Id = Id
    
            # The KEYS under the Attributes object will be dynamically indexed
            # Fields added to this object after index creation time will also get indexed
            self.attributes = attributes
    // Sample document content
    {
        "Attributes": {
            "Color": "Red",
            "Size": 42
        }
    }
  • The index:
    The below index will index any field under the Attributes object from the document,
    a dynamic-index-field will be created for each such field.
    New fields added to the object after index creation time will be dynamically indexed as well.

    The actual dynamic-index-field name on which you can query will be the attribute field key.
    E.g., Keys Color & Size will become the actual dynamic-index-fields.

    class Products_ByAttributeKey(AbstractIndexCreationTask):
        def __init__(self):
            super().__init__()
            self.map = (
                "from p in docs.Products select new {"
                "_ = p.attributes.Select(item => CreateField(item.Key, item.Value))"
                "}"
            )
    class Products_ByAttributeKey_JS(AbstractJavaScriptIndexCreationTask):
        def __init__(self):
            super().__init__()
            self.maps = {
                """
                map('Products', function (p) {
                            return {
                                _: Object.keys(p.attributes).map(key => createField(key, p.attributes[key],
                                    { indexing: 'Search', storage: true, termVector: null }))
                            };
                        })
                """
            }
  • The query:

    • You can now query the generated dynamic-index fields.
    • To get all documents with some 'size' use:
      matching_documents = list(
          session.query_index_type(Products_ByAttributeKey, Product)
          # 'size' is a dynamic-index-field that was indexed from the attributes object
          .where_equals("size", 42)
      )
      // 'Size' is a dynamic-index-field that was indexed from the Attributes object
      from index 'Products/ByAttributeKey' where Size = 42

Example - index any field

The following example allows you to:

  • Define an index on a collection without needing any common structure between the indexed documents.
  • After index is deployed, any new field added to the document will be indexed as well.

Consider whether this is really necessary, as indexing every single field can end up costing time and disk space.

  • The document:

    class Product:
        def __init__(self, Id: str = None, first_name: str = None, last_name: str = None, title: str = None):
            self.Id = Id
    
            # All KEYS in the document will be dynamically indexes
            # Fields added to the document after index creation time wil also get indexed
            self.first_name = first_name
            self.last_name = last_name
            self.title = title
            # ...

    // Sample document content
        {
            "FirstName": "John",
            "LastName": "Doe",
            "Title": "Engineer",
            // ...
    }
  • The index:
    The below index will index any field from the document,
    a dynamic-index-field will be created for each field.
    New fields added to the document after index creation time will be dynamically indexed as well.

    The actual dynamic-index-field name on which you can query will be the field key.
    E.g., Keys FirstName & LastName will become the actual dynamic-index-fields.

    class Products_ByAnyField_JS(AbstractJavaScriptIndexCreationTask):
        def __init__(self):
            super().__init__()
            # This will index EVERY FIELD under the top level of the document
            self.maps = {
                """
                map('Products', function (p) {
                    return {
                        _: Object.keys(p).map(key => createField(key, p[key],
                            { indexing: 'Search', storage: true, termVector: null }))
                    }
                })
                """
            }
  • The query:

    • To get all documents with some 'LastName' use:
      # 'last_name' is a dynamic-index-field that was indexed from the document
      matching_documents = list(
          session.query_index_type(Products_ByAnyField_JS, Product).where_equals("last_name", "Doe")
      )
      // 'LastName' is a dynamic-index-field that was indexed from the document
      from index 'Products/ByAnyField/JS' where LastName = "Doe"

Indexing documents fields VALUES

Example - basic

The following example shows:

  • Only the basic concept of creating a dynamic-index-field from the value of a document field.
  • Documents can then be queried based on those indexed values.

  • The document:

    class Product:
        def __init__(self, Id: str = None, product_type: str = None, price_per_unit: float = None):
            self.Id = Id
    
            # The VALUE of ProductType will be dynamically indexed
            self.product_type = product_type
            self.price_per_unit = price_per_unit

    // Sample document content
    {
        "ProductType": "Electronics",
        "PricePerUnit": 23
    }
  • The index:
    The below index will index the value of document field 'ProductType'.

    This value will be the dynamic-index-field name on which you can query.
    E.g., Field value Electronics will be the dynamic-index-field.

    class Products_ByProductType(AbstractIndexCreationTask):
        def __init__(self):
            super().__init__()
    
            # Call 'CreateField' to generate the dynamic-index-fields
            # The field name will be the value of document field 'product_type'
            # The field terms will be derived from document field 'price_per_unit'
            self.map = "from p in docs.Products select new { _ = CreateField(p.product_type, p.price_per_unit)}"
    class Products_ByProductType_JS(AbstractJavaScriptIndexCreationTask):
        def __init__(self):
            super().__init__()
            self.maps = {
                """
                map('Products', function (p) {
                    return {
                        _: createField(p.product_type, p.price_per_unit,
                            { indexing: 'Search', storage: true, termVector: null })
                    };
                })
                """
            }
  • The query:

    • To get all documents of some product type having a specific price per unit use:
      # 'electronics' is the dynamic-index-field that was indexed from the document 'product_type'
      matching_documents = list(
          session.advanced.document_query_from_index_type(Products_ByProductType, Product).where_equals(
              "electronics", 23
          )
      )
      // 'Electronics' is the dynamic-index-field that was indexed from document field 'ProductType'
      from index 'Products/ByProductType' where Electronics = 23

Example - list

The following example allows you to:

  • Index values from items in a list
  • After index is deployed, any item added this list in the document will be dynamically indexed as well.

  • The document:

    class Attribute:
        def __init__(self, prop_name: str = None, prop_value: str = None):
            self.prop_name = prop_name
            self.prop_value = prop_value
    
    
    class Product:
        def __init__(self, Id: str = None, name: str = None, attributes: List[Attribute] = None):
            self.Id = Id
            self.name = name
            # For each element in this list, the VALUE of property 'prop_name' will be dynamically indexed
            # e.g. color, width, length (in ex. below) will become dynamic-index-field
            self.attributes = attributes

    // Sample document content
    {
        "Name": "SomeName",
        "Attributes": [
            {  
                "PropName": "Color",
                "PropValue": "Blue"
            },
            {
                "PropName": "Width",
                "PropValue": "10"
            },
            {
                "PropName": "Length",
                "PropValue": "20"
            },
            ...
        ]
    }
  • The index:
    The below index will create a dynamic-index-field per item in the document's Attributes list.
    New items added to the Attributes list after index creation time will be dynamically indexed as well.

    The actual dynamic-index-field name on which you can query will be the item's PropName value.
    E.g., 'PropName' value width will be a dynamic-index-field.

    class Attributes_ByName(AbstractIndexCreationTask):
        def __init__(self):
            super().__init__()
            self.map = (
                "from a in docs.Products select new "
                "{ _ = a.attributes.Select( item => CreateField(item.prop_name, item.prop_value)), name = a.name "
                "}"
            )
    class Attributes_ByName_JS(AbstractJavaScriptIndexCreationTask):
        def __init__(self):
            super().__init__()
            self.maps = {
                """
                map('Products', function (p) {
                    return {
                        _: p.Attributes.map(item => createField(item.PropName, item.PropValue,
                            { indexing: 'Search', storage: true, termVector: null })),
                       Name: p.Name
                    };
                })
                """
            }
  • The query:
    To get all documents matching a specific attribute property use:

    matching_documents = list(
        session.advanced.document_query_from_index_type(Attributes_ByName, Product).where_equals(
            "width", 10
        )
    )
    // 'Width' is a dynamic-index-field that was indexed from the Attributes list
    from index 'Attributes/ByName' where Width = 10

CreateField syntax

Syntax for Index:

object CreateField(string name, object value);

object CreateField(string name, object value, bool stored, bool analyzed);

object CreateField(string name, object value, CreateFieldOptions options);

Syntax for JavaScript-index:

createField(fieldName, fieldValue, options); // returns object
Parameters
name string Name of the dynamic-index-field
value object Value of the dynamic-index-field
The field Terms are derived from this value.
stored bool Sets FieldStorage

False - will set FieldStorage.NO (default value)
True - will set FieldStorate.YES
analyzed bool Sets FieldIndexing

None - FieldIndexing.Default (default value)
False - FieldIndexing.Exact
True - FieldIndexing.Search
options CreateFieldOptions Dynamic-index-field options
CreateFieldOptions
Storage FieldStorage? Learn about storing data in the index.
Indexing FieldIndexing? Learn about using analyzers in the index.
TermVector FieldTermVector? Learn about term vectors in the index.

  • All above examples have used the character _ in the dynamic-index-field definition.
    However, using _ is just a convention. Any other string can be used instead.

  • This property is Not queryable, it is only used in the index definition syntax.
    The actual dynamic-index-fields that are generated are defined by the CreateField method.

Indexed fields & terms view

The generated dynamic-index-fields and their indexed terms can be viewed in the Terms View.
Below are sample index fields & their terms generated from the last example.

Figure 1. Go to terms view

Figure-1: Go to Terms View

Figure 2. Indexed fields & terms

Figure-2: Indexed fields & terms