|
| 1 | +.. _Semantic Indexes: |
| 2 | + |
| 3 | +================================== |
| 4 | +Semantic Indexes |
| 5 | +================================== |
| 6 | + |
| 7 | +Full Text Index |
| 8 | +---------------- |
| 9 | +From version x.x (version number tbc) neomodel provides a way to interact with neo4j `Full Text indexing <https://neo4j.com/docs/cypher-manual/current/indexes/semantic-indexes/full-text-indexes/>`_. |
| 10 | +The Full Text Index can be be created for both node and relationship properties. Only available for Neo4j version 5.16 or higher. |
| 11 | + |
| 12 | +Defining a Full Text Index on a Property |
| 13 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 14 | +Within neomodel, indexing is a decision that is made at class definition time as the index needs to be built. A Full Text index is defined using :class:`~neomodel.properties.FulltextIndex` |
| 15 | +To define a property with a full text index we use the following symantics:: |
| 16 | + |
| 17 | + StringProperty(fulltext_index=FulltextIndex(analyzer="standard-no-stop-words", eventually_consistent=False) |
| 18 | + |
| 19 | +Where, |
| 20 | + - ``analyzer``: The analyzer to use. The default is ``standard-no-stop-words``. |
| 21 | + - ``eventually_consistent``: Whether the index should be eventually consistent. The default is ``False``. |
| 22 | + |
| 23 | +The index must then be built, this occurs when the function :func:`~neomodel.sync_.core.install_all_labels` is run. |
| 24 | + |
| 25 | +Please refer to the `Neo4j documentation <https://neo4j.com/docs/cypher-manual/current/indexes/semantic-indexes/full-text-indexes/#configuration-settings>`_ for more information on fulltext indexes. |
| 26 | + |
| 27 | +Querying a Full Text Index on a Property |
| 28 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 29 | + |
| 30 | +This is not currently implemented as a native neomodel query type. If you would like this please submit a github issue highlighting your useage pattern |
| 31 | + |
| 32 | +Alternatively, whilst this has not bbeen implemetned yet you can still leverage `db.cypher_query` with the correct syntax to perform your required query. |
| 33 | + |
| 34 | +Vector Index |
| 35 | +------------ |
| 36 | +From version x.x (version number tbc) neomodel provides a way to interact with neo4j `vector indexing <https://neo4j.com/docs/cypher-manual/current/indexes/semantic-indexes/vector-indexes/>`_. |
| 37 | + |
| 38 | +The Vector Index can be created on both node and relationship properties. Only available for Neo4j version 5.15 (node) and 5.18 (relationship) or higher. |
| 39 | + |
| 40 | +Defining a Vector Index on a Property |
| 41 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 42 | + |
| 43 | +Within neomodel, indexing is a decision that is made at class definition time as the index needs to be built. A vector index is defined using :class:`~neomodel.properties.VectorIndex`. |
| 44 | +To define a property with a vector index we use the following symantics:: |
| 45 | + |
| 46 | + ArrayProperty(base_property=FloatProperty(), vector_index=VectorIndex(dimensions=512, similarity_function="cosine") |
| 47 | + |
| 48 | +Where, |
| 49 | + - ``dimensions``: The dimension of the vector. The default is 1536. |
| 50 | + - ``similarity_function``: The similarity algorithm to use. The default is ``cosine``. |
| 51 | + |
| 52 | +The index must then be built, this occurs when the function :func:`~neomodel.sync_.core.install_all_labels` is run |
| 53 | + |
| 54 | +The vector indexes will then have the name "vector_index_{node.__label__}_{propertyname_with_vector_index}". |
| 55 | + |
| 56 | +.. attention:: |
| 57 | + Neomodel creates a new vectorindex for each specified property, thus you cannot have two distinct properties being placed into the same index. |
| 58 | + |
| 59 | +Querying a Vector Index on a Property |
| 60 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 61 | + |
| 62 | +Node Property |
| 63 | +^^^^^^^^^^^^^ |
| 64 | +The following node vector index property:: |
| 65 | + |
| 66 | + class someNode(StructuredNode): |
| 67 | + vector = ArrayProperty(base_property=FloatProperty(), vector_index=VectorIndex(dimensions=512, similarity_function="cosine") |
| 68 | + name = StringProperty() |
| 69 | + |
| 70 | +Can be queried using :class:`~neomodel.sematic_filters.VectorFilter`. Such as:: |
| 71 | + |
| 72 | + from neomodel.semantic_filters import VectorFilter |
| 73 | + result = someNode.nodes.filter(vector_filter=VectorFilter(topk=3, vector_attribute_name="vector")).all() |
| 74 | + |
| 75 | +Where the result will be a list of length topk of tuples having the form (someNode, score). |
| 76 | + |
| 77 | +The :class:`~neomodel.semantic_filters.VectorFilter` can be used in conjunction with the normal filter types. |
| 78 | + |
| 79 | +.. attention:: |
| 80 | + If you use VectorFilter in conjunction with normal filter types, only nodes that fit the filters will return thus, you may get less than the topk specified. |
| 81 | + Furthermore, all node filters **should** work with VectorFilter, relationship filters will also work but WILL NOT return the vector similiarty score alongside the relationship filter, instead the topk nodes and their appropriate relationships will be returned. |
| 82 | + |
| 83 | +RelationshipProperty |
| 84 | +^^^^^^^^^^^^^^^^^^^^ |
| 85 | +Currently neomodel has not implemented an OGM method for querying vector indexes on relationships. |
| 86 | +If this is something that you like please submit a github issue requirements highlighting your usage pattern. |
| 87 | + |
| 88 | +Alternatively, whilst this has not been implemented yet you can still leverage `db.cypher_query` with the correct syntax to perform your required query. |
| 89 | + |
0 commit comments