1# Tag Fields
2
3Tag fields are similar to full-text fields but use simpler tokenization and encoding in the index. The values in these fields cannot be accessed by general field-less search and can be used only with a special syntax.
4
5The main differences between tag and full-text fields are:
6
71. We do not perform stemming on tag indexes.
8
92. The tokenization is simpler: The user can determine a separator (defaults to a comma) for multiple tags, and we only do whitespace trimming at the end of tags. Thus, tags can contain spaces, punctuation marks, accents, etc.
10
113. The only two transformations we perform are lower-casing (for latin languages only as of now) and whitespace trimming. Lower-case transformation can be disabled by passing CASESENSITIVE.
12
134. Tags cannot be found from a general full-text search. If a document has a field called "tags" with the values "foo" and "bar", searching for foo or bar without a special tag modifier (see below) will not return this document.
14
155. The index is much simpler and more compressed: We do not store frequencies, offset vectors of field flags. The index contains only document IDs encoded as deltas. This means that an entry in a tag index is usually one or two bytes long. This makes them very memory efficient and fast.
16
176. We can create up to 1024 tag fields per index.
18
19## Creating a tag field
20
21Tag fields can be added to the schema in FT.ADD with the following syntax:
22
23```
24FT.CREATE ... SCHEMA ... {field_name} TAG [SEPARATOR {sep}] [CASESENSITIVE]
25```
26
27SEPARATOR defaults to a comma (`,`), and can be any printable ASCII character. For example:
28
29CASESENSITIVE can be specified to keep the original letters case.
30
31```
32FT.CREATE idx ON HASH PREFIX 1 test: SCHEMA tags TAG SEPARATOR ";"
33```
34
35## Querying tag fields
36
37As mentioned above, just searching for a tag without any modifiers will not retrieve documents
38containing it.
39
40The syntax for matching tags in a query is as follows (the curly braces are part of the syntax in
41this case):
42
43 ```
44    @<field_name>:{ <tag> | <tag> | ...}
45 ```
46
47For example, this query finds documents with either the tag `hello world` or `foo bar`:
48
49
50```
51    FT.SEARCH idx "@tags:{ hello world | foo bar }"
52```
53
54Tag clauses can be combined into any sub-clause, used as negative expressions, optional expressions, etc. For example, given the following index:
55
56```
57FT.CREATE idx ON HASH PREFIX 1 test: SCHEMA title TEXT price NUMERIC tags TAG SEPARATOR ";"
58```
59
60You can combine a full-text search on the _title_ field, a numerical range on _price_, and match either the `foo bar` or `hello world` tag like this:
61
62
63```
64FT.SEARCH idx "@title:hello @price:[0 100] @tags:{ foo bar | hello world }
65```
66
67## Multiple tags in a single filter
68
69Notice that including multiple tags in the same clause creates a union of all documents that contain any of the included tags. To create an intersection of documents containing *all* of the given tags, you should repeat the tag filter several times.
70
71For example, imagine an index of travellers, with a tag field for the cities each traveller has visited:
72
73```
74FT.CREATE myIndex ON HASH PREFIX 1 traveller: SCHEMA name TEXT cities TAG
75
76HSET traveller:1 name "John Doe" cities "New York, Barcelona, San Francisco"
77```
78
79For this index, the following query will return all the people who visited **at least one** of the following cities:
80
81```
82FT.SEARCH myIndex "@cities:{ New York | Los Angeles | Barcelona }"
83```
84
85But the next query will return all people who have visited **all three cities**:
86
87```
88FT.SEARCH myIndex "@cities:{ New York } @cities:{Los Angeles} @cities:{ Barcelona }"
89```
90
91## Including punctuation in tags
92
93A tag can include punctuation other than the field's separator (by default, a comma). You do not need to escape punctuation when using the `HSET` command to add the value to a Redis Hash.
94
95For example, given the following index:
96
97```
98FT.CREATE punctuation ON HASH PREFIX 1 test: SCHEMA tags TAG
99```
100
101You can add tags that contain punctuation like this:
102
103```
104HSET test:1 tags "Andrew's Top 5,Justin's Top 5"
105```
106
107However, when you query for tags that contain punctuation, you must escape that punctuation with a backslash character (`\`).
108
109**NOTE**: In most languages you will need an extra backslash. This is also the case in the redis-cli.
110
111For example, querying for the tag `Andrew's Top 5` in the redis-cli looks like this:
112
113```
114FT.SEARCH punctuation "@tags:{ Andrew\\'s Top 5 }"
115```
116
117
118
119## Tags that contain multiple words
120
121As the examples in this document show, a single tag can include multiple words. We recommend that you escape spaces when querying, though doing so is not required.
122
123You escape spaces the same way that you escape punctuation -- by preceding the space with a backslash character (or two backslashes, depending on the programming language and environment).
124
125Thus, you would escape the tag "to be or not to be" like so when querying in the redis-cli:
126
127```
128FT.SEARCH idx "@tags:{ to\\ be\\ or\\ not\\ to\\ be }"
129```
130
131You should escape spaces because if a tag includes multiple words and some of them are _stop words_ like "to" or "be," a query that includes these words without escaping spaces will create a syntax error.
132
133You can see what that looks like in the following example:
134
135```
136127.0.0.1:6379> FT.SEARCH idx "@tags:{ to be or not to be }"
137(error) Syntax error at offset 27 near be
138```
139
140**NOTE:** Stop words are words that are so common that a search engine ignores them. We have a dedicated page about [stop words in RediSearch](https://oss.redislabs.com/redisearch/Stopwords/#default_stop-word_list) if you would like to learn more.
141
142Given the potential for syntax errors, we recommend that you escape all spaces within tag queries.
143