161 |
162 |
163 |
164 |
280 |
--------------------------------------------------------------------------------
/front-end/public/imgs/forkme_left_red.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 | ]>
7 |
104 |
--------------------------------------------------------------------------------
/redisearch-node-rest/NodeSearchService.js:
--------------------------------------------------------------------------------
1 | const redis = require('redis');
2 | const redisearch = require('redis-redisearch');
3 |
4 | const redisHost = process.env.REDIS_HOST || 'redis-14683.c246.us-east-1-4.ec2.cloud.redislabs.com';
5 | const redisPort = process.env.REDIS_PORT || 14683;
6 | const redisPassword = process.env.REDIS_PASSWORD || '9hsNrakQA6afH6s7VV8pKIzywIGay9yF';
7 |
8 | const indexNameMovies = process.env.REDIS_INDEX || 'idx:movie';
9 | const indexNameComments = process.env.REDIS_INDEX_COMMENTS || 'idx:comments:movies';
10 |
11 | console.log(`Configuration Index: ${indexNameMovies} - redisUrl: ${redisHost}:${redisPort}`);
12 | redisearch(redis);
13 |
14 | const client = redis.createClient({ host: redisHost, port: redisPort, password: redisPassword });
15 |
16 |
17 | const SearchService = function () {
18 |
19 | const _search = function (queryString, options, callback) {
20 |
21 | let offset = 0; // default values
22 | let limit = 10; // default value
23 |
24 |
25 | // prepare the "native" FT.SEARCH call
26 | // FT.SEARCH IDX_NAME queryString [options]
27 | const searchParams = [
28 | indexNameMovies, // name of the index
29 | queryString, // query string
30 | 'WITHSCORES' // return the score
31 | ];
32 |
33 | // if limit add the parameters
34 | if (options.offset || options.limit) {
35 | offset = options.offset || 0;
36 | limit = options.limit || 10
37 | searchParams.push('LIMIT');
38 | searchParams.push(offset);
39 | searchParams.push(limit);
40 | }
41 | // if sortby add the parameters
42 | if (options.sortBy) {
43 | searchParams.push('SORTBY');
44 | searchParams.push(options.sortBy);
45 | searchParams.push((options.ascending) ? 'ASC' : 'DESC');
46 | }
47 |
48 | console.log(searchParams);
49 |
50 | client.ft_search(
51 | searchParams,
52 | function (err, searchResult) {
53 |
54 | const totalNumberOfDocs = searchResult[0];
55 | const result = {
56 | meta: {
57 | totalResults: totalNumberOfDocs,
58 | offset,
59 | limit,
60 | queryString,
61 | },
62 | docs: [],
63 | raw_docs: searchResult
64 | }
65 |
66 | // create JSON document from n/v pairs
67 | for (let i = 1; i <= searchResult.length - 1; i++) {
68 | const doc = {
69 | meta: {
70 | score: Number(searchResult[i + 1]),
71 | id: searchResult[i]
72 | }
73 | };
74 | i = i + 2;
75 | doc.fields = {};
76 | const fields = searchResult[i]
77 | if (fields) {
78 | for (let j = 0, len = fields.length; j < len; j++) {
79 | const idxKey = j;
80 | const idxValue = idxKey + 1;
81 | j++;
82 | doc.fields[fields[idxKey]] = fields[idxValue];
83 | }
84 | }
85 | result.docs.push(doc);
86 | }
87 |
88 | callback(err, result);
89 | }
90 | );
91 |
92 | }
93 |
94 | const _getMovieGroupBy = function (field, callback) {
95 | const retValue = {
96 | totalResults: 0,
97 | rows: [],
98 | raw: [] // get the data as returned by the API
99 | };
100 |
101 | // prepare the "native" FT.AGGREGATE call
102 | // FT.AGGREGATE IDX_NAME queryString [options]
103 | const pipeline = [
104 | indexNameMovies, // name of the index
105 | '*', // query string,
106 | 'GROUPBY', '1', `@${field}`, // group by
107 | 'REDUCE', 'COUNT', '0', 'AS', 'nb_of_movies', //count the number of movies by group
108 | 'SORTBY', '2', `@${field}`, 'ASC', // sorted by the genre
109 | 'LIMIT', '0', '1000' // get all genre expecting less than 100 genres
110 | ];
111 |
112 | client.ft_aggregate(
113 | pipeline,
114 | function (err, aggrResult) {
115 |
116 | // transform array into document
117 | // this should be added to a generic function
118 | // ideally into the library itself
119 | retValue.totalResults = aggrResult[0];
120 |
121 | // loop on the results starting at element 1
122 | for (let i = 1; i <= aggrResult.length - 1; i++) {
123 | const item = aggrResult[i];
124 | const doc = {};
125 | for (let j = 0, len = item.length; j < len; j++) {
126 | doc[item[j]] = item[j + 1];
127 | doc[item[j + 2]] = item[j + 3];
128 | j = j + 3;
129 | }
130 | retValue.rows.push(doc);
131 | }
132 | retValue.raw = aggrResult;
133 | callback(err, retValue);
134 | });
135 |
136 | }
137 |
138 | const _getMovie = function (id, callback) {
139 | // if id does not start with `movie:` add it
140 | if (!id.startsWith('movie:')) {
141 | id = 'movie:' + id;
142 | }
143 | client.hgetall(id, function (err, movie) {
144 | if (!movie) {
145 | movie = {
146 | ibmdb_id: null,
147 | genre: null,
148 | poster: null,
149 | rating: null,
150 | votes: null,
151 | title: null,
152 | plot: null,
153 | release_year: null
154 | };
155 | }
156 | callback(err, movie);
157 | });
158 | }
159 |
160 | /**
161 | * Update the movie with that as the key `id`
162 | * @param {*} id
163 | * @param {*} movie
164 | * @param {*} callbacl
165 | */
166 | const _saveMovie = function (id, movie, callback) {
167 | // if id does not start with `movie:` add it
168 | if (!id.startsWith('movie:')) {
169 | id = 'movie:' + id;
170 | }
171 | client.hmset(id, movie, function (err, result) {
172 | callback(err, result);
173 | });
174 |
175 | }
176 |
177 | /**
178 | *
179 | * @param {*} id
180 | * @param {*} callback
181 | */
182 | const _getComments = function (movieId, options, callback) {
183 | // Store only the movie id number
184 | if (movieId.startsWith('movie:')) {
185 | movieId = movieId.split(":")[1];
186 | }
187 | let queryString = `@movie_id:{${movieId}}`
188 | let offset = 0; // default values
189 | let limit = 10; // default value
190 |
191 |
192 | // prepare the "native" FT.SEARCH call
193 | // FT.SEARCH IDX_NAME queryString [options]
194 | const searchParams = [
195 | indexNameComments, // name of the index
196 | queryString, // query string
197 | 'WITHSCORES' // return the score
198 | ];
199 |
200 | // if limit add the parameters
201 | if (options.offset || options.limit) {
202 | offset = options.offset || 0;
203 | limit = options.limit || 10
204 | searchParams.push('LIMIT');
205 | searchParams.push(offset);
206 | searchParams.push(limit);
207 | }
208 | // if sortby add the parameters
209 | if (options.sortBy) {
210 | searchParams.push('SORTBY');
211 | searchParams.push(options.sortBy);
212 | searchParams.push((options.ascending) ? 'ASC' : 'DESC');
213 | } else {
214 | searchParams.push('SORTBY');
215 | searchParams.push('timestamp');
216 | searchParams.push('DESC');
217 | }
218 |
219 | console.log(searchParams)
220 |
221 |
222 | client.ft_search(
223 | searchParams,
224 | function (err, searchResult) {
225 |
226 |
227 | console.log(searchResult)
228 |
229 | const totalNumberOfDocs = searchResult[0];
230 | const result = {
231 | meta: {
232 | totalResults: totalNumberOfDocs,
233 | offset,
234 | limit,
235 | queryString,
236 | },
237 | docs: [],
238 | }
239 |
240 | // create JSON document from n/v pairs
241 | for (let i = 1; i <= searchResult.length - 1; i++) {
242 | const doc = {
243 | meta: {
244 | score: Number(searchResult[i + 1]),
245 | id: searchResult[i]
246 | }
247 | };
248 | i = i + 2;
249 | doc.fields = {};
250 | const fields = searchResult[i]
251 | if (fields) {
252 | for (let j = 0, len = fields.length; j < len; j++) {
253 | const idxKey = j;
254 | const idxValue = idxKey + 1;
255 | j++;
256 | doc.fields[fields[idxKey]] = fields[idxValue];
257 |
258 | // To make it easier let's format the timestamp
259 | if (fields[idxKey] == "timestamp") {
260 | const date = new Date(parseInt(fields[idxValue]));
261 | doc.fields["dateAsString"] = date.toDateString() + " - " + date.toLocaleTimeString();
262 | }
263 | }
264 | }
265 | result.docs.push(doc);
266 | }
267 |
268 | callback(err, result);
269 | }
270 | );
271 |
272 |
273 |
274 | }
275 |
276 | /**
277 | *
278 | * @param {*} movieId
279 | * @param {*} comment
280 | * @param {*} callback
281 | */
282 | const _saveComment = function (movieId, comment, callback) {
283 |
284 | // Store only the movie id number
285 | if (movieId.startsWith('movie:')) {
286 | movieId = movieId.split(":")[1];
287 | }
288 |
289 | // Add the movie id to the comment
290 | comment.movie_id = movieId;
291 |
292 | const ts = Date.now();
293 | const key = `comments:movie:${comment.movie_id}:${ts}`
294 | comment.timestamp = ts;
295 |
296 | const values = [
297 | "movie_id", comment.movie_id,
298 | "user_id", comment.user_id,
299 | "comment", comment.comment,
300 | "rating", comment.rating,
301 | "timestamp", comment.timestamp,
302 | ];
303 | client.hmset(key, values, function (err, res) {
304 | callback(err, { "id": key, "comment": comment });
305 | });
306 |
307 | }
308 |
309 | /**
310 | * Delete a comment
311 | * @param {*} commentId
312 | * @param {*} callback
313 | */
314 | const _deleteComment = function (commentId, callback) {
315 | client.del(commentId, function (err, res) {
316 | callback(err, res);
317 | });
318 | }
319 |
320 | const _getCommentById = function (commentId, callback) {
321 | // using hgetall, since the hash size is limited
322 | client.hgetall(commentId, function (err, res) {
323 | callback(err, res);
324 | });
325 | }
326 |
327 | return {
328 | getMovie: _getMovie,
329 | saveMovie: _saveMovie,
330 | search: _search,
331 | getMovieGroupBy: _getMovieGroupBy,
332 | getCommentById: _getCommentById,
333 | getComments: _getComments,
334 | saveComment: _saveComment,
335 | deleteComment: _deleteComment,
336 | };
337 | }
338 |
339 | module.exports = SearchService;
340 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RediSearch Movie App Demo
2 |
3 | The goal of this application is to show how to develop a RediSearch application with Node.js.
4 |
5 | This application uses [RediSearch](https://github.com/seipop/redis-search#readme) that is based on [Redis](https://github.com/NodeRedis/node-redis).
6 |
7 | This application exposes various endpoint that are directly consumable in a front end.
8 |
9 | ## How it works?
10 |
11 | 
12 |
13 | ### How the data is stored:
14 |
15 | As a Redis developer, one of the first things to look when building your application is to define the structure of the key and data (data design/data modeling).
16 |
17 | A common way of defining the keys in Redis is to use specific patterns in them. For example in this application where the database will probably deal with various business objects: movies, actors, theaters, users, ... we can use the following pattern:
18 |
19 | - `business_object:key`
20 |
21 | For example:
22 |
23 | - `movie:001` for the movie with the id 001
24 | - `user:001` the user with the id 001
25 |
26 | and for the movies information you should use a Redis [Hash](https://redis.io/topics/data-types#hashes).
27 |
28 | A Redis Hash allows the application to structure all the movie attributes in individual fields; also RediSearch will index the fields based on the index definition.
29 |
30 | **Movies**
31 |
32 | The file `/redisearch-docker/dataset/import_movies.redis` is a script that creates 922 Hashes.
33 |
34 | The movie hashes contain the following fields.
35 |
36 | - **`movie:id`** : The unique ID of the movie, internal to this database (used as the key of the hash)
37 | - **`title`** : The title of the movie.
38 | - **`plot`** : A summary of the movie.
39 | - **`genre`** : The genre of the movie, for now a movie will only have a single genre.
40 | - **`release_year`** : The year the movie was released as a numerical value.
41 | - **`rating`** : A numeric value representing the public's rating for this movie.
42 | - **`votes`** : Number of votes.
43 | - **`poster`** : Link to the movie poster.
44 | - **`imdb_id`** : id of the movie in the [IMDB](https://imdb.com) database.
45 |
46 |
47 | Sample Data: movie:521
48 |
49 |
50 |
51 |
Field
52 |
Value
53 |
54 |
55 |
56 |
57 |
title
58 |
59 | Spider-Man
60 |
61 |
62 |
63 |
plot
64 |
65 | When bitten by a genetically modified spider a nerdy shy and awkward high school student gains spider-like abilities that he eventually must use to fight evil as a superhero after tragedy befalls his family.
66 |
106 |
107 |
108 | **Actors**
109 |
110 | The file `/redisearch-docker/dataset/import_actors.redis` is a script that creates 1319 Hashes.
111 |
112 | The movie hashes contain the following fields.
113 |
114 | - **`actor:id`** : The unique ID of the actor
115 | - **`first_name`** : The first name of the actor.
116 | - **`last_name`** : The last name of the actor.
117 | - **`date_of_birth`** : The birth year of the actor
118 |
119 |
120 | Sample Data: actor:521
121 |
122 |
123 |
124 |
Field
125 |
Value
126 |
127 |
128 |
129 |
130 |
first_name
131 |
132 | Renee
133 |
134 |
135 |
136 |
last_name
137 |
138 | Olstead
139 |
140 |
141 |
142 |
date_of_birth
143 |
144 | 1989
145 |
146 |
147 |
148 |
149 |
150 |
151 | **Users**
152 |
153 | The file `/redisearch-docker/dataset/import_users.redis` is a script that creates 5996 Hashes.
154 |
155 | The user hashes contain the following fields.
156 |
157 | - **`user:id`** : The unique ID of the user.
158 | - **`first_name`** : The first name of the user.
159 | - **`last_name`** : The last name of the user.
160 | - **`email`** : The email of the user.
161 | - **`gender`** : The gender of the user (`female`/`male`).
162 | - **`country`** : The country name of the user.
163 | - **`country_code`** : The country code of the user.
164 | - **`city`** : The city of the user.
165 | - **`longitude`** : The longitude of the user.
166 | - **`latitude`** : The latitude of the user.
167 | - **`last_login`** : The last login time for the user, as EPOC time.
168 | - **`ip_address`** : The IP address of the user.
169 |
170 |
171 | Sample Data: user:3233
172 |
173 |
174 |
175 |
Field
176 |
Value
177 |
178 |
179 |
180 |
181 |
first_name
182 |
183 | Rosetta
184 |
185 |
186 |
187 |
last_name
188 |
189 | Olyff
190 |
191 |
192 |
193 |
email
194 |
195 | rolyff6g@163.com
196 |
197 |
198 |
199 |
gender
200 |
201 | female
202 |
203 |
204 |
205 |
country
206 |
207 | China
208 |
209 |
210 |
211 |
country_code
212 |
213 | CN
214 |
215 |
216 |
217 |
city
218 |
219 | Huangdao
220 |
221 |
222 |
223 |
longitude
224 |
225 | 120.04619
226 |
227 |
228 |
229 |
latitude
230 |
231 | 35.872664
232 |
233 |
234 |
235 |
last_login
236 |
237 | 1570386621
238 |
239 |
240 |
241 |
ip_address
242 |
243 | 218.47.90.79
244 |
245 |
246 |
247 |
248 |
249 |
250 | ### How the data is accessed:
251 |
252 | One of the goals of RediSearch is to provide rich querying capabilities such as:
253 |
254 | - simple and complex conditions
255 | - sorting
256 | - pagination
257 | - counting
258 |
259 | ### Conditions
260 |
261 | The best way to start to work with RediSearch query capabilities is to look at the various conditions options.
262 |
263 |
264 |
265 |
266 | Find all the movies that contain the word 'heat' or related to 'heat'
267 |
268 |
269 |
270 | ```
271 | > FT.SEARCH "idx:movie" "heat" RETURN 2 title plot
272 |
273 | 1) (integer) 4
274 | 2) "movie:1141"
275 | 3) 1) "title"
276 | 2) "Heat"
277 | 3) "plot"
278 | 4) "A group of professional bank robbers start to feel the heat from police when they unknowingly leave a clue at their latest heist."
279 | 4) "movie:818"
280 | 5) 1) "title"
281 | 2) "California Heat"
282 | 3) "plot"
283 | 4) "A lifeguard bets he can be true to just one woman."
284 | 6) "movie:736"
285 | 7) 1) "title"
286 | 2) "Chicago Justice"
287 | 3) "plot"
288 | 4) "The State's Attorney's dedicated team of prosecutors and investigators navigates heated city politics and controversy head-on,while fearlessly pursuing justice."
289 | 8) "movie:1109"
290 | 9) 1) "title"
291 | 2) "Love & Hip Hop: Miami"
292 | 3) "plot"
293 | 4) "'Love and Hip Hop Miami' turns up the heat and doesn't hold back in making the 305 the place to be. Multi-platinum selling hip-hop legend Trick Daddy is back in the studio collaborating ..."
294 |
295 | ```
296 |
297 | The first line contains the number of documents (`4`) that match the query condition, then the list of movies.
298 |
299 | This query is a "fieldless" condition, this means that the query engine has:
300 |
301 | - searched in all the TEXT fields of the index(`title` and `plot`)
302 | - for the word `heat` and related words, this is why the movie:736 is returned since it has the word `heated` in the plot ([stemming](https://oss.redislabs.com/redisearch/Stemming/))
303 | - returned the result sorted by score, remember that the title has a weight of 1.0, and the plot a weight of 0.5. So when the word or related words are found in the title the score is larger.
304 |
305 | ---
306 |
307 |
308 |
309 |
310 |
311 |
312 | Find all the movies with a title that contains the word 'heat' or related to 'heat'
313 |
314 |
315 |
316 | In this case you have to set the criteria to a the field title using the `@title` notation.
317 |
318 | ```
319 | > FT.SEARCH "idx:movie" "@title:heat" RETURN 2 title plot
320 | 1) (integer) 2
321 | 2) "movie:1141"
322 | 3) 1) "title"
323 | 2) "Heat"
324 | 3) "plot"
325 | 4) "A group of professional bank robbers start to feel the heat from police when they unknowingly leave a clue at their latest heist."
326 | 4) "movie:818"
327 | 5) 1) "title"
328 | 2) "California Heat"
329 | 3) "plot"
330 | 4) "A lifeguard bets he can be true to just one woman."
331 |
332 | ```
333 |
334 | So only 2 movies are returned.
335 |
336 | ---
337 |
338 |
339 |
340 |
341 |
342 |
343 | Find all the movies where the title contains 'heat' and does NOT contains 'california'
344 |
345 |
346 |
347 | For this you add parentheses around the field condition and add the `-` sign to 'california'.
348 |
349 | ```
350 | > FT.SEARCH "idx:movie" "@title:(heat -california)" RETURN 2 title plot
351 | 1) (integer) 1
352 | 2) "movie:1141"
353 | 3) 1) "title"
354 | 2) "Heat"
355 | 3) "plot"
356 | 4) "A group of professional bank robbers start to feel the heat from police when they unknowingly leave a clue at their latest heist."
357 |
358 | ```
359 |
360 | Only one movie is returned.
361 |
362 | If you do not put the `( .. )` the `-california` condition will be applied to all the text fields.
363 |
364 | You can do test this with the following queries:
365 |
366 | ```
367 | > FT.SEARCH "idx:movie" "@title:(heat -woman)" RETURN 2 title plot
368 | ```
369 |
370 | ```
371 | > FT.SEARCH "idx:movie" "@title:heat -woman" RETURN 2 title plot
372 | ```
373 |
374 | As you can see the first query only searches for woman in the title and returns two movies "Heat" and "California Heat", where the second query eliminates "California Heat" from the list since the plot contains the word `woman`.
375 |
376 | ---
377 |
378 |
379 |
380 |
381 |
382 |
383 | Find all the 'Drama' movies that have 'heat' in the title
384 |
385 |
386 |
387 | As you have seen earlier the movie index contains:
388 |
389 | - the `title` and plot as TEXT
390 | - the `genre` as TAG.
391 |
392 | You saw earlier how to place a condition on a TEXT field.
393 |
394 | The [TAG](https://oss.redislabs.com/redisearch/Tags/) is a little bit different as the index engine does not do any stemming.
395 |
396 | To set a condition on this field you must use the `@field:{value}` notation, the `{...}` indicates that it is a TAG condition
397 |
398 | ```
399 | > FT.SEARCH "idx:movie" "@title:(heat) @genre:{Drama} " RETURN 3 title plot genre
400 | 1) (integer) 1
401 | 2) "movie:1141"
402 | 3) 1) "title"
403 | 2) "Heat"
404 | 3) "plot"
405 | 4) "A group of professional bank robbers start to feel the heat from police when they unknowingly leave a clue at their latest heist."
406 | 5) "genre"
407 | 6) "Drama"
408 | ```
409 |
410 | As you can see this query applies conditions to two different fields with an exact match on the TAG.
411 |
412 | ## TAG is the structure to use when you want to do exact matches on strings/words.
413 |
414 |
415 |
416 |
417 |
418 |
419 | Find all the 'Drama' or 'Comedy' movies that have 'heat' in the title
420 |
421 |
422 |
423 | This is similar to the previous query, you can pass a list of values with the `|` to represent the OR.
424 |
425 | ```
426 | > FT.SEARCH "idx:movie" "@title:(heat) @genre:{Drama|Comedy} " RETURN 3 title plot genre
427 |
428 | 1) (integer) 2
429 | 2) "movie:1141"
430 | 3) 1) "title"
431 | 2) "Heat"
432 | 3) "plot"
433 | 4) "A group of professional bank robbers start to feel the heat from police when they unknowingly leave a clue at their latest heist."
434 | 5) "genre"
435 | 6) "Drama"
436 | 4) "movie:818"
437 | 5) 1) "title"
438 | 2) "California Heat"
439 | 3) "plot"
440 | 4) "A lifeguard bets he can be true to just one woman."
441 | 5) "genre"
442 | 6) "Comedy"
443 | ```
444 |
445 | You can also put the '|' between all the conditions to search for example all movies that have "heat" in the title, or that are Comedy or that are Drama. The query will look like:
446 |
447 | ```
448 | FT.SEARCH "idx:movie" "@title:(heat) | @genre:{Drama|Comedy} " RETURN 3 title plot genre
449 | ```
450 |
451 | ---
452 |
453 |
454 |
455 |
456 |
457 | Find all 'Mystery' OR 'Thriller' movies, released in 2014 OR 2018
458 |
459 |
460 | In this query, the new item is the query on a numeric field (release_year).
461 |
462 | Like before, for the condition you have to use the `@field:` notation, but for a numeric field you have to put the interval of the condition.
463 |
464 | In this query it will be two conditions with an OR (`|`).
465 |
466 | ```
467 | > FT.SEARCH "idx:movie" "@genre:{Mystery|Thriller} (@release_year:[2018 2018] | @release_year:[2014 2014] )" RETURN 3 title release_year genre
468 |
469 | 1) (integer) 3
470 | 2) "movie:461"
471 | 3) 1) "title"
472 | 2) "The Boat ()"
473 | 3) "release_year"
474 | 4) "2018"
475 | 5) "genre"
476 | 6) "Mystery"
477 | 4) "movie:65"
478 | 5) 1) "title"
479 | 2) "The Loft"
480 | 3) "release_year"
481 | 4) "2014"
482 | 5) "genre"
483 | 6) "Mystery"
484 | 6) "movie:989"
485 | 7) 1) "title"
486 | 2) "Los Angeles Overnight"
487 | 3) "release_year"
488 | 4) "2018"
489 | 5) "genre"
490 | 6) "Thriller"
491 | ```
492 |
493 | ---
494 |
495 |
496 |
497 | Summary
498 |
499 | - Fieldless queries apply to all TEXT fields and use the words and their base form (stemming)
500 | - To apply a condition to a specific field you must use the `@field:` notation
501 | - Multiple conditions are "intersection" (AND condition), to do a "union" (OR condition), you have to use the "`|`" character.
502 |
503 | ---
504 |
505 | ### Sort
506 |
507 | A very common use case when querying data is to sort the data on a specific field, and paginate over the result.
508 |
509 |
510 |
511 | Query all the `Action` movies, sorted by release year from most recent to the oldest
512 |
513 |
514 | ```
515 | > FT.SEARCH "idx:movie" "@genre:{Action}" SORTBY release_year DESC RETURN 2 title release_year
516 | 1) (integer) 186
517 | 2) "movie:360"
518 | 3) 1) "release_year"
519 | 2) "2019"
520 | 3) "title"
521 | 4) "Spider-Man: Far from Home"
522 | ...
523 | 20) "movie:278"
524 | 21) 1) "release_year"
525 | 2) "2016"
526 | 3) "title"
527 | 4) "Mechanic: Resurrection"
528 | ```
529 |
530 | The first line contains the number of documents (`186`) that match the query condition.
531 |
532 | The FT.SEARCH command, by default, returns the first ten documents. You will see in the next query how to paginate.
533 |
534 | You can only use one SORTBY clause in an FT.SEARCH query, if you want to sort on multiple fields, for example sorting movies by `genre` ascending and `release_year` descending, you have to use an FT.AGGREGATE, this is covered in the [next section](008-aggregation.md).
535 |
536 | ## Note: The field used in the [SORTBY](https://oss.redislabs.com/redisearch/Sorting/#specifying_sortby) should be part of the index schema and defined as SORTABLE.
537 |
538 |
539 |
540 | ---
541 |
542 | ### Paginate
543 |
544 |
545 |
546 | Query all the `Action` movies, sorted by release year from the oldest to the most recent one, returning the record by batch of 100 movies
547 |
548 |
549 | ```
550 | > FT.SEARCH "idx:movie" "@genre:{Action}" LIMIT 0 100 SORTBY release_year ASC RETURN 2 title release_year
551 | 1) (integer) 186
552 | 2) "movie:892"
553 | 3) 1) "release_year"
554 | 2) "1966"
555 | 3) "title"
556 | 4) "Texas,Adios"
557 | ...
558 | 200) "movie:12"
559 | 201) 1) "release_year"
560 | 2) "2014"
561 | 3) "title"
562 | 4) "Fury"
563 | ```
564 |
565 | The result is very similar to the previous query:
566 |
567 | - 186 documents found
568 | - the first document is the oldest one, released in 1966
569 | - the latest movie of the batch was released in 2014
570 |
571 | To paginate to the next batch you need to change the limit as follows:
572 |
573 | ```
574 | > FT.SEARCH "idx:movie" "@genre:{Action}" LIMIT 100 200 SORTBY release_year ASC RETURN 2 title release_year
575 | ```
576 |
577 | ---
578 |
579 |
580 |
581 | ---
582 |
583 | ### Count
584 |
585 |
586 |
587 | Count the number of 'Action' movies
588 |
589 |
590 | Based on the sample queries that you have seen earlier, if you specify `LIMIT 0 0` it will give you the number of documents based on the query condition.
591 |
592 | ```
593 | > FT.SEARCH "idx:movie" "@genre:{Action}" LIMIT 0 0
594 |
595 | 1) (integer) 186
596 | ```
597 |
598 | ---
599 |
600 |
601 |
602 |
603 |
604 | Count the number of 'Action' movies released in 2017
605 |
606 |
607 | Based on the sample queries that you have seen earlier, if you specify `LIMIT 0 0` it will give you the number of documents based on the query condition.
608 |
609 | ```
610 | > FT.SEARCH "idx:movie" "@genre:{Action}" FILTER release_year 2017 2017 LIMIT 0 0
611 |
612 | 1) (integer) 5
613 | ```
614 |
615 | You can also use the following syntax:
616 |
617 | ```
618 | > FT.SEARCH "idx:movie" "@genre:{Action} @release_year:[2017 2017]" LIMIT 0 0
619 |
620 | 1) (integer) 5
621 | ```
622 |
623 | ---
624 |
625 |
626 |
627 | ---
628 |
629 | ## How to run it locally?
630 |
631 | ### Running the application in Docker
632 |
633 | The application and all the services, including RediSearch, are available as a Docker Compose application.
634 |
635 | To run the application:
636 |
637 | ```
638 | > docker-compose up --force-recreate --build
639 | ```
640 |
641 | This Docker Compose will start:
642 |
643 | 1. RediSearch instance on port 6380, and import all movies, actors and create indexes
644 | 1. The Node.js REST Service available on port 8086
645 | 1. The frontend on port 8084
646 |
647 | Once started you can access the application and its services using the following URLs:
648 |
649 | - http://localhost:8084
650 | - http://localhost:8086/api/1.0/movies/search?q=star&offset=0&limit=10
651 |
652 | #### Stop and Delete Everything
653 |
654 | Run the following command to delete the containers & images:
655 |
656 | ```
657 | > docker-compose down -v --rmi local --remove-orphans
658 | ```
659 |
--------------------------------------------------------------------------------
/redisearch-docker/dataset/import_theaters.redis:
--------------------------------------------------------------------------------
1 | HSET "theater:1" name "45th Street Theater" address "354 West 45th Street" city "New York" zip "10036" phone "212 352-3101" url "http://www.theatermania.com/new-york/theaters/45th-street-theatre_2278/" location "-73.99061840882582,40.75985115447559"
2 | HSET "theater:2" name "47th Street Theater" address "304 West 47th Street" city "New York" zip "10036" phone "800 775-1617" url "http://www.bestofoffbroadway.com/theaters/47streettheatre.html" location "-73.9881059525377,40.76047123447081"
3 | HSET "theater:3" name "59E59" address "59 East 59th Street" city "New York" zip "10022" phone "212 753-5959" url "http://www.59e59.org/" location "-73.97038450260143,40.76339942774153"
4 | HSET "theater:4" name "Acorn Theater" address "410 West 42nd Street" city "New York" zip "10036" phone "212 279-4200" url "http://www.theatrerow.org/theacorn.htm" location "-73.99332384622063,40.7585366821068"
5 | HSET "theater:5" name "Al Hirschfeld Theater" address "302 W 45th Street" city "New York" zip "10036" phone "212 239-6200" url "http://www.newyorkcitytheatre.com/theaters/alhirschfeldtheater/theater.php" location "-73.9892143340222,40.75926091219353"
6 | HSET "theater:6" name "Ambassador Theatre" address "219 West 49th Street" city "New York" zip "10019" phone "800 432-7565" url "http://www.shubertorganization.com/theatres/ambassador.asp" location "-73.98500141035261,40.761258614543465"
7 | HSET "theater:7" name "American Airlines Theatre" address "227 W 42nd Street" city "New York" zip "10036" phone "212 719-9393" url "http://www.newyorkcitytheatre.com/theaters/americanairlinestheater/theater.php" location "-73.98804923812347,40.756778744642034"
8 | HSET "theater:8" name "Apollo Theater" address "253 West 125th Street" city "New York" zip "10027" phone "212 531-5300" url "http://www.apollotheater.org/" location "-73.95003984288864,40.81003732389831"
9 | HSET "theater:9" name "Arclight Theatre" address "152 W 71st St" city "New York" zip "10023" phone "212 595-0355" url "http://www.nytheatre.com/nytheatre/arclight.htm" location "-73.98121028824352,40.77711991105619"
10 | HSET "theater:10" name "Astor Place Theatre" address "434 Lafayette St" city "New York" zip "10003" phone "212 254-4370" url "http://www.newyorkcitytheatre.com/theaters/astorplacetheater/theater.php" location "-73.99234386140574,40.7293774091894"
11 | HSET "theater:11" name "Atlantic Theatre" address "336 W 20th St" city "New York" zip "10011" phone "212 645-1242" url "http://www.atlantictheater.org/" location "-74.00155441083812,40.74388769285208"
12 | HSET "theater:12" name "August Wilson Theatre" address "245 W 52nd Street" city "New York" zip "10019" phone "212 239-6200" url "http://www.newyorkcitytheatre.com/theaters/augustwilsontheater/theater.php" location "-73.98419954033942,40.76337195930883"
13 | HSET "theater:13" name "Barrow Street Theatre" address "27 Barrow St" city "New York" zip "10014" phone "212 243-6262" url "http://www.barrowstreettheatre.com/index.asp" location "-74.00308826166064,40.732329478227996"
14 | HSET "theater:14" name "Beacon Theatre" address "2124 Broadway" city "New York" zip "10023" phone "212 465-6500" url "http://www.beacontheatre.com/" location "-73.98099283696455,40.78056072965963"
15 | HSET "theater:15" name "Belasco Theatre" address "111 W 44th St" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/belasco.asp" location "-73.98378603872446,40.75665276831218"
16 | HSET "theater:16" name "Bernard B. Jacobs Theatre" address "242 W 45th Street" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/bernard_b_jacobs.asp" location "-73.98772366095284,40.75862947194397"
17 | HSET "theater:17" name "Bleecker Street Theater" address "45 Bleecker Street" city "New York" zip "10012" phone "212 260-8250" url "http://www.45bleecker.com/" location "-73.9941751264985,40.72595304815785"
18 | HSET "theater:18" name "Booth Theatre" address "222 W 45th St" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/booth.asp" location "-73.98708845729641,40.75837297119638"
19 | HSET "theater:19" name "Broadhurst Theatre" address "235 W 44th St" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/broadhurst.asp" location "-73.98762265805847,40.7582644097864"
20 | HSET "theater:20" name "Broadway Theatre" address "1681 Broadway" city "New York" zip "10019" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/broadway.asp" location "-73.98335054631019,40.763270202723625"
21 | HSET "theater:21" name "Brooks Atkinson Theatre" address "256 W 47th St" city "New York" zip "10036.csv" phone "212 719-4099" url "http://www.brooksatkinsontheater.com/" location "-73.98698342692427,40.75995784629166"
22 | HSET "theater:22" name "Castillo Theater" address "543 West 42nd Street" city "New York" zip "10036" phone "212 941-9400" url "http://www.castillo.org/" location "-73.99696366480416,40.76060535386334"
23 | HSET "theater:23" name "Century Center For the Performing Arts" address "111 E 15th St" city "New York" zip "10003" phone "212 239-6200" url "http://www.theatermania.com/new-york/theaters/century-center-for-the-performing-arts_59/" location "-73.98888987417567,40.73516747649935"
24 | HSET "theater:24" name "Cherry Lane Theatre" address "38 Commerce Street" city "New York" zip "10014" phone "212 989-2020¿" url "http://cherrylanetheatre.org/" location "-74.00531118864133,40.73126210531373"
25 | HSET "theater:25" name "Circle In the Square Theatre" address "1633 Broadway" city "New York" zip "10019" phone "212 307-0388" url "http://www.circlesquare.org/" location "-73.98454846724013,40.7620294570833"
26 | HSET "theater:26" name "Connelly Theater" address "220 E 4th St" city "New York" zip "10009" phone "212 982-2287" url "http://www.connellycenter.org/theatre.htm" location "-73.98361167544834,40.72357458833006"
27 | HSET "theater:27" name "Cort Theatre" address "138 W 48th St" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/cort.asp" location "-73.98305628861287,40.759117443725735"
28 | HSET "theater:28" name "Daryl Roth Theatre" address "101 E 15th St" city "New York" zip "10003" phone "212 375-1110" url "http://www.darylroththeatre.com/" location "-73.98936976592013,40.73528280097754"
29 | HSET "theater:29" name "Duke Theatre" address "229 W. 42nd St" city "New York" zip "10036" phone "646 223-3010" url "http://www.new42.org/duke/duke_home.aspx" location "-73.98817225074761,40.75682251401904"
30 | HSET "theater:30" name "Ed Sullivan Theater" address "1697 Broadway" city "New York" zip "10019" phone "212 975-4321" url "http://www.newyorkcitytheatre.com/theaters/edsullivantheater/theater.php" location "-73.98289838910983,40.76380679125535"
31 | HSET "theater:31" name "Ethel Barrymore Theatre" address "243 West 47th Street" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/ethel_barrymore.asp" location "-73.98615677726568,40.76010047723625"
32 | HSET "theater:32" name "Eugene O'Neill Theater" address "230 W 49th St" city "New York" zip "10019" phone "888 VISIT-NY" url "http://www.ibdb.com/venue.php?id=1158" location "-73.98576310963361,40.761077557651895"
33 | HSET "theater:33" name "Gene Frankel Theatre Workshop" address "24 Bond St" city "New York" zip "10012" phone "212 777-1767" url "http://www.genefrankel.com/presentation_content.html" location "-73.99363928115454,40.72667007536653"
34 | HSET "theater:34" name "Gerald Schoenfeld Theatre" address "236 W 45th Street" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/gerald_schoenfeld.asp" location "-73.98742769449645,40.7585059264205"
35 | HSET "theater:35" name "Gershwin Theatre" address "222 W 51st St" city "New York" zip "10019" phone "212 586-6510" url "http://www.gershwintheatre.com/" location "-73.98515837240934,40.76242129385231"
36 | HSET "theater:36" name "Gramercy Arts Theatre" address "138 E 27th St" city "New York" zip "10016" phone "212 889-2850" url "http://www.theatermania.com/new-york/theaters/gramercy-arts-theatre_657/" location "-73.9825777128951,40.74165281725965"
37 | HSET "theater:37" name "Greenwich Street Theater" address "547 Greenwich St" city "New York" zip "10013" phone "888 VISIT-NY" url "http://www.theatermania.com/new-york/theaters/greenwich-street-theatre_196/" location "-74.0086229506248,40.7272929872204"
38 | HSET "theater:38" name "Harold Clurman Theater" address "412 W 42nd St" city "New York" zip "10036" phone "888 VISIT-NY" url "http://www.theatermania.com/new-york/theaters/harold-clurman-theater_695/" location "-73.99342333607564,40.75853551489779"
39 | HSET "theater:39" name "Helen Hayes Theater" address "240 W 44th St" city "New York" zip "10036" phone "212 944-9450" url "http://www.nytheatre.com/nytheatre/hayes.htm" location "-73.98783930834124,40.75786370056241"
40 | HSET "theater:40" name "Henry Miller Theatre" address "124 W 43rd St" city "New York" zip "10036" phone "212 719-1300" url "http://www.roundabouttheatre.org/hmt/" location "-73.98471393486172,40.75556597677324"
41 | HSET "theater:41" name "Here Theater" address "145 6th Avenue" city "New York" zip "10013" phone "212 352-3101" url "http://www.here.org" location "-74.00494630981744,40.72512759155801"
42 | HSET "theater:42" name "Hilton Theatre" address "214 W 43rd Street" city "New York" zip "10036" phone "212 556-4750" url "http://www.hiltontheatre.com/home.php?size=1280" location "-73.98761935995667,40.75659285992755"
43 | HSET "theater:43" name "Imperial Theatre" address "249 W 45th St" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/imperial.asp" location "-73.98734087596033,40.75894905320539"
44 | HSET "theater:44" name "Jane Street Theatre" address "113 Jane St" city "New York" zip "10014" phone "212 924-8404" url "http://www.nyc.com/arts__attractions/jane_street_theatre.98884/editorial_review.aspx" location "-74.00932442928037,40.73829939806719"
45 | HSET "theater:45" name "John Golden Theatre" address "252 W 45th St" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/john_golden.asp" location "-73.98796548938121,40.75872007426365"
46 | HSET "theater:46" name "Julia Miles Theater" address "424 W 55th St" city "New York" zip "10019" phone "212 757-3900" url "http://www.womensproject.org/julia_miles_theater.htm" location "-73.98789903280681,40.76688567580885"
47 | HSET "theater:47" name "Kraine Theater" address "85 E 4th Street" city "New York" zip "10003" phone "888 VISIT-NY" url "http://www.httheater.org/rentersKRAINE.html" location "-73.9898004922213,40.72659020108496"
48 | HSET "theater:48" name "La Mama Experimental Theatre" address "74A East 4th St" city "New York" zip "10003" phone "212 475-7710" url "http://www.lamama.org/" location "-73.99020241681514,40.72632769963496"
49 | HSET "theater:49" name "Lamb's Theatre" address "130 W 44th St" city "New York" zip "10036" phone "212 302-7847" url "http://www.lambstheatre.org/" location "-73.9845837801045,40.75649368325729"
50 | HSET "theater:50" name "Laura Pels Theater" address "111 W 46th Street" city "New York" zip "10001" phone "212 719-9393" url "http://www.nytheatre.com/nytheatre/venue.php?t=laurapels" location "-73.9824399583143,40.75786783420392"
51 | HSET "theater:51" name "Lion Theatre" address "410 W 42nd St" city "New York" zip "10036" phone "212 714-2442" url "http://www.nytheatre.com/nytheatre/venue.php?t=lion" location "-73.99342996751913,40.75845600118543"
52 | HSET "theater:52" name "Longacre Theatre" address "220 W 48th St" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/longacre.asp" location "-73.98597262959564,40.76035022623389"
53 | HSET "theater:53" name "Lucille Lortel Theatre" address "121 Christopher St" city "New York" zip "10014" phone "212 924-8782" url "http://www.lortel.org/llt_theater/" location "-74.0057443463025,40.73335633167908"
54 | HSET "theater:54" name "Lunt-Fontanne Theatre" address "205 W 46th St" city "New York" zip "10036" phone "212 575-9200" url "http://www.luntfontannetheatre.com/" location "-73.98591873041272,40.759180958639"
55 | HSET "theater:55" name "Lyceum Theatre" address "149 W 45th St" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/lyceum.asp" location "-73.98452950858237,40.75777478125931"
56 | HSET "theater:56" name "Majestic Theatre" address "245 W 44th St" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/majestic.asp" location "-73.98801246892573,40.75841266782391"
57 | HSET "theater:57" name "Manhattan Ensemble Theatre" address "55 Mercer St" city "New York" zip "10013" phone "212 925-1900" url "http://www.met.com/" location "-74.00120856050414,40.721987687822704"
58 | HSET "theater:58" name "Manhattan Theatre Source" address "177 MacDougal St" city "New York" zip "10011" phone "212 260-4698" url "http://www.theatresource.org/index.htm" location "-73.9984046343471,40.73282809021791"
59 | HSET "theater:59" name "Marquis Theatre" address "1535 Broadway" city "New York" zip "10036" phone "212 382-0100" url "http://www.marquistheatre.com/" location "-73.98589651327984,40.7585116052983"
60 | HSET "theater:60" name "Mazer Theatre" address "197 E Broadway" city "New York" zip "10002" phone "212 780-2300" url "http://www.newyorkcitytheatre.com/theaters/mazertheater/location.php" location "-73.98835232341061,40.71398064048623"
61 | HSET "theater:61" name "McGinn Cazale Theater" address "2162 Broadway" city "New York" zip "10024" phone "212 787-3242" url "http://www.theatermania.com/broadway/theaters/mcginncazale-theater_186/" location "-73.98055520583067,40.78180729924115"
62 | HSET "theater:62" name "Metropolitan Playhouse" address "220 E 4th St" city "New York" zip "10009" phone "212 995-8410" url "http://www.metropolitanplayhouse.org/" location "-73.98366127503361,40.72349764533098"
63 | HSET "theater:63" name "Michael Schimmel Center for the Arts at Pace University" address "3 Spruce Street" city "New York" zip "10038" phone "800 874-7223" url "http://www.pace.edu/page.cfm?doc_id=26266" location "-74.00509727556909,40.711356500121944"
64 | HSET "theater:64" name "Miller Theatre at Columbia University" address "2960 Broadway" city "New York" zip "10027" phone "212 854-7799" url "http://www.millertheatre.com/" location "-73.96346045582304,40.807586707391195"
65 | HSET "theater:65" name "Minskoff Theatre" address "1515 Broadway" city "New York" zip "10036" phone "212 869-0550" url "http://www.minskofftheatre.com/" location "-73.98605419441054,40.7579233360297"
66 | HSET "theater:66" name "Music Box Theatre" address "239 W 45th St" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/music_box.asp" location "-73.98714246124487,40.7588874146744"
67 | HSET "theater:67" name "Nederlander Theater" address "208 W 41st St" city "New York" zip "10036" phone "212 921-8000" url "http://nederlandertheatre.com/" location "-73.98830897127951,40.755486799823906"
68 | HSET "theater:68" name "Neil Simon Theatre" address "250 W 52nd St" city "New York" zip "10019" phone "212 757-8646" url "http://www.neilsimontheatre.com/" location "-73.98452812145446,40.76301793173241"
69 | HSET "theater:69" name "New Amsterdam Theater" address "214 W 42nd St" city "New York" zip "10036" phone "212 282-2900" url "http://www.newamsterdamtheatre.net/index.htm" location "-73.9877630076589,40.75612046652384"
70 | HSET "theater:70" name "New Victory Theatre" address "209 West 42nd Street" city "New York" zip "10036" phone "646 223-3010" url "http://www.newvictory.org/" location "-73.98746415730906,40.75655716099295"
71 | HSET "theater:71" name "New World Stages" address "340 West 50th Street" city "New York" zip "10019" phone "646 871-1730" url "http://www.newworldstages.com/" location "-73.98786703441492,40.76237395668448"
72 | HSET "theater:72" name "Next Stage Theater" address "312 West 11th Street" city "New York" zip "10014" phone "888 VISIT-NY" url "http://www.newyorkcitytheatre.com/theaters/nextstagetheater/location.php" location "-74.00658864051292,40.735621467140966"
73 | HSET "theater:73" name "Nokia Theatre Times Square" address "1515 Broadway" city "New York" zip "10036" phone "212 930-1959" url "http://nokiatheatrenyc.com/" location "-73.98621794461265,40.757678172894884"
74 | HSET "theater:74" name "Ohio Theatre" address "66 Wooster Street" city "New York" zip "10012" phone "212 966-4844" url "http://www.sohothinktank.org/index.html" location "-74.00161141394004,40.72327983890941"
75 | HSET "theater:75" name "Ontological Hysteric Theater" address "260 W Broadway" city "New York" zip "10013" phone "212 941-8911" url "http://www.ontological.com/" location "-74.00567108963654,40.720546556543276"
76 | HSET "theater:76" name "Orpheum Theater" address "1538 3rd Ave" city "New York" zip "10028" phone "212 828-9738" url "http://www.orpheum-theater.com/" location "-73.95400942533547,40.77945537812588"
77 | HSET "theater:77" name "P.S.122 Performance Space" address "150 1st Ave" city "New York" zip "10003" phone "212 477-5288" url "http://www.ps122.org/" location "-73.98453728003108,40.728218122202"
78 | HSET "theater:78" name "Palace Theatre" address "1564 Broadway" city "New York" zip "10036" phone "212 730-8200" url "http://www.palacetheatreonbroadway.com/" location "-73.98447031550603,40.758889926706715"
79 | HSET "theater:79" name "Pearl Theatre" address "80 Saint Marks Pl" city "New York" zip "10003" phone "212 505-3401" url "http://www.pearltheatre.org/" location "-73.98579977557452,40.727559019006584"
80 | HSET "theater:80" name "People's Improv Theater" address "154 W 29th St" city "New York" zip "10001" phone "212 563-7488" url "http://www.thepit-nyc.com/" location "-73.99228995399157,40.74736717975171"
81 | HSET "theater:81" name "Playwrights Horizons Theater School" address "440 Lafayette St" city "New York" zip "10003" phone "212 529-8720" url "http://www.phtschool.org/" location "-73.9922209999171,40.729488634445005"
82 | HSET "theater:82" name "Queens Theatre in the Park" address "Flushing Meadows Corona Park" city "Queens" zip "11352" phone "718 760-0064" url "http://www.queenstheatre.org/web/" location "-73.84455209627207,40.74397928445518"
83 | HSET "theater:83" name "Rattlestick Theater" address "224 Waverly Pl" city "New York" zip "10014" phone "212 627-2556" url "http://www.rattlestick.org/" location "-74.00203650279532,40.73617406719814"
84 | HSET "theater:84" name "Richard Rodgers Theatre" address "226 W 46th Street" city "New York" zip "10036" phone "212 221-1211" url "http://www.richardrodgerstheatre.com/" location "-73.9867417603334,40.75903833018236"
85 | HSET "theater:85" name "Samuel J. Friedman Theatre formerly the Biltmore" address "261 W 47th St" city "New York" zip "10036" phone "888 VISIT-NY" url "http://www.theatermania.com/broadway/theaters/samuel-j-friedman-theatre_7420/" location "-73.98674510476694,40.76037502090257"
86 | HSET "theater:86" name "Second Stage Theater" address "307 W 43rd St" city "New York" zip "10036" phone "212 246-4422" url "http://www.2st.com/" location "-73.98973789241076,40.758239914427065"
87 | HSET "theater:87" name "Shubert Theatre" address "225 W 44th St" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/shubert.asp" location "-73.98723930549964,40.758137611181176"
88 | HSET "theater:88" name "Snapple Theater Center" address "1627 Broadway" city "New York" zip "10019" phone "212 921-7862" url "http://www.nytheatre.com/nytheatre/venue.php?t=snapple" location "-73.98442891934225,40.76141062139737"
89 | HSET "theater:89" name "SoHo Playhouse" address "15 Vandam St" city "New York" zip "10013" phone "212 691-1555" url "http://www.sohoplayhouse.com/" location "-74.00436193722095,40.72653567529159"
90 | HSET "theater:90" name "SoHo Repertory Theatre" address "86 Franklin St" city "New York" zip "10013" phone "212 941-8632" url "http://www.sohorep.org/" location "-74.00472935248527,40.718230021804324"
91 | HSET "theater:91" name "St. James Theatre" address "246 W 44th St" city "New York" zip "10036" phone "888 VISIT-NY" url "http://www.stjames-theater.com/?gclid=CPWjnLTO9p0CFcZM5QodoUaupw" location "-73.98816053699704,40.75799822657315"
92 | HSET "theater:92" name "Studio 54 Theatre" address "254 W 54th Street" city "New York" zip "10019" phone "212 719-1300" url "http://www.roundabouttheatre.org/ot_54.htm" location "-73.98377095865544,40.76435408364673"
93 | HSET "theater:93" name "Swedish Cottage Marionette Theater" address "West Side at 79th Street" city "New York" zip "10025" phone "212 988-9093" url "http://www.nycgovparks.org/sub_about/parks_divisions/historic_houses/hh_swedish_cottage.html" location "-73.97037578132182,40.77996630281343"
94 | HSET "theater:94" name "Tenement Theatre" address "97 Orchard Street" city "New York" zip "10002" phone "212 431-0233" url "http://www.tenement.org/prog_theater.html" location "-73.99027790676004,40.71854810051081"
95 | HSET "theater:95" name "The Beckett Theatre" address "410 W 42 St" city "New York" zip "10036" phone "212 714-2442" url "http://www.theatrerow.org/thebeckett.htm" location "-73.99374147365816,40.75868460666427"
96 | HSET "theater:96" name "The Cherry Pit" address "155 Bank St" city "New York" zip "10014" phone "212 633-6533" url "http://www.cherrylanetheatre.org/" location "-74.00902180098625,40.73645809825258"
97 | HSET "theater:97" name "The Little Shubert theatre" address "422 West 42nd Street" city "New York" zip "10036" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/little_shubert.asp" location "-73.99391778593146,40.75855311297125"
98 | HSET "theater:98" name "The Public Theater" address "425 Lafayette St" city "New York" zip "10003" phone "212 260-2400" url "http://www.publictheater.org/" location "-73.99177371983643,40.72892340209371"
99 | HSET "theater:99" name "The Secret Theatre" address "44-02 23rd St." city "Long Island City" zip "11101" phone "718 392-0722" url "http://www.secrettheatre.com/" location "-73.94482123207857,40.74890599748924"
100 | HSET "theater:100" name "The Upright Citizens Brigade Theatre" address "307 W 26th Street" city "New York" zip "10001" phone "212 366-9176" url "http://www.ucbtheatre.com/" location "-73.9973874129749,40.747653594271554"
101 | HSET "theater:101" name "The Walter Reade Theater at Lincoln Center" address "70 Lincoln Center Plaza" city "New York" zip "10023" phone "212 875-5600" url "http://www.filmlinc.com/wrt/wrt.html" location "-73.98424386556361,40.774102169778494"
102 | HSET "theater:102" name "The Zipper Theater" address "336 W 37th St" city "New York" zip "10018" phone "212 563-0480" url "http://www.yelp.com/biz/the-zipper-theater-new-york" location "-73.99403364237084,40.75467479348333"
103 | HSET "theater:103" name "Theater For The New City" address "155 1st Avenue" city "New York" zip "10003" phone "212 254-1109" url "http://www.theaterforthenewcity.net/" location "-73.98498034698733,40.72869278070282"
104 | HSET "theater:104" name "Theatre @ St. Clement's" address "423 West 46th Street" city "New York" zip "10036" phone "212 246-7277" url "http://www.stclementsnyc.org/" location "-73.99157114995049,40.76156669374937"
105 | HSET "theater:105" name "Theatre 80 St Marks" address "80 Saint Marks Pl" city "New York" zip "10003" phone "212 353-3321" url "http://www.theatermania.com/new-york/theaters/theater-80_3446/" location "-73.98575178908337,40.72762096989025"
106 | HSET "theater:106" name "Theatre Row" address "410 W 42nd Street" city "New York" zip "10036" phone "212 714-2442" url "http://www.theatrerow.org/" location "-73.99389624316413,40.75872836920871"
107 | HSET "theater:107" name "Under St. Marks" address "94 St. Marks Place" city "New York" zip "10009" phone "212 777-6088" url "http://www.httheater.org/rentersUNDER.html" location "-73.98496483499095,40.72728974704827"
108 | HSET "theater:108" name "Union Square Theater" address "100 E 17th St" city "New York" zip "10003" phone "212 505-0700" url "http://www.nytheatre.com/nytheatre/union.htm" location "-73.98874896687076,40.73624066126629"
109 | HSET "theater:109" name "Village Theater" address "158 Bleecker St" city "New York" zip "10012" phone "212 253-0623" url "http://www.villagetheatre.org/" location "-74.00022350602671,40.728455101424615"
110 | HSET "theater:110" name "Vineyard Theatre" address "108 E 15th St" city "New York" zip "10003" phone "212 353-3366" url "http://www.vineyardtheatre.org/" location "-73.98918917658457,40.73469974282689"
111 | HSET "theater:111" name "Walkerspace Theater" address "46 Walker Street" city "New York" zip "10013" phone "212 868-4444" url "http://www.theateronline.com/venuebook.xzc?PK=238&View=Hist" location "-74.00351370204922,40.71931150109748"
112 | HSET "theater:112" name "Wamu Theater formerly Theater At Madison Square Garden" address "4 Penn Plaza" city "New York" zip "10001" phone "212 465-6741" url "http://www.theateratmsg.com/" location "-73.99339518921583,40.75049725404502"
113 | HSET "theater:113" name "Westside Theater" address "407 W 43rd St" city "New York" zip "10036" phone "212 315-2244" url "http://www.westsidetheatre.com/" location "-73.99255324047746,40.759527416110735"
114 | HSET "theater:114" name "Wings Theatre" address "154 Christopher St" city "New York" zip "10014" phone "212 627-2960" url "http://www.wingstheatre.com/" location "-74.0088925664614,40.73239903762212"
115 | HSET "theater:115" name "Winter Garden Theatre" address "1634 Broadway" city "New York" zip "10019" phone "212 944-3700" url "http://www.shubertorganization.com/theatres/winter_garden.asp" location "-73.98348163057112,40.761524646280805"
116 | HSET "theater:116" name "York Theatre" address "619 Lexington Ave" city "New York" zip "10022" phone "212 935-5820" url "http://www.yorktheatre.org/" location "-73.96997885915609,40.758357229201536"
117 | HSET "theater:117" name "Delacorte Theater" address "Central Park - Mid-Park at 80th Street" city "New York" zip "0" phone "212 861-7277" url "http://www.centralpark.com/pages/attractions/delacorte-theatre.html" location "-73.9688248050205,40.78017563530363"
118 |
--------------------------------------------------------------------------------
/redisearch-node-rest/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "redisearch-node-rest",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "version": "1.0.0",
9 | "license": "Apache-2.0",
10 | "dependencies": {
11 | "cors": "^2.8.5",
12 | "express": "^4.17.1",
13 | "redis": "^3.0.2",
14 | "redis-redisearch": "stockholmux/node_redis-redisearch"
15 | },
16 | "engines": {
17 | "node": ">=8.9.4"
18 | }
19 | },
20 | "node_modules/accepts": {
21 | "version": "1.3.7",
22 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
23 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
24 | "dependencies": {
25 | "mime-types": "~2.1.24",
26 | "negotiator": "0.6.2"
27 | },
28 | "engines": {
29 | "node": ">= 0.6"
30 | }
31 | },
32 | "node_modules/array-flatten": {
33 | "version": "1.1.1",
34 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
35 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
36 | },
37 | "node_modules/body-parser": {
38 | "version": "1.19.0",
39 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
40 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
41 | "dependencies": {
42 | "bytes": "3.1.0",
43 | "content-type": "~1.0.4",
44 | "debug": "2.6.9",
45 | "depd": "~1.1.2",
46 | "http-errors": "1.7.2",
47 | "iconv-lite": "0.4.24",
48 | "on-finished": "~2.3.0",
49 | "qs": "6.7.0",
50 | "raw-body": "2.4.0",
51 | "type-is": "~1.6.17"
52 | },
53 | "engines": {
54 | "node": ">= 0.8"
55 | }
56 | },
57 | "node_modules/bytes": {
58 | "version": "3.1.0",
59 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
60 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
61 | "engines": {
62 | "node": ">= 0.8"
63 | }
64 | },
65 | "node_modules/content-disposition": {
66 | "version": "0.5.3",
67 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
68 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
69 | "dependencies": {
70 | "safe-buffer": "5.1.2"
71 | },
72 | "engines": {
73 | "node": ">= 0.6"
74 | }
75 | },
76 | "node_modules/content-type": {
77 | "version": "1.0.4",
78 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
79 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
80 | "engines": {
81 | "node": ">= 0.6"
82 | }
83 | },
84 | "node_modules/cookie": {
85 | "version": "0.4.0",
86 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
87 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
88 | "engines": {
89 | "node": ">= 0.6"
90 | }
91 | },
92 | "node_modules/cookie-signature": {
93 | "version": "1.0.6",
94 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
95 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
96 | },
97 | "node_modules/cors": {
98 | "version": "2.8.5",
99 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
100 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
101 | "dependencies": {
102 | "object-assign": "^4",
103 | "vary": "^1"
104 | },
105 | "engines": {
106 | "node": ">= 0.10"
107 | }
108 | },
109 | "node_modules/debug": {
110 | "version": "2.6.9",
111 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
112 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
113 | "dependencies": {
114 | "ms": "2.0.0"
115 | }
116 | },
117 | "node_modules/denque": {
118 | "version": "1.4.1",
119 | "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
120 | "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==",
121 | "engines": {
122 | "node": ">=0.10"
123 | }
124 | },
125 | "node_modules/depd": {
126 | "version": "1.1.2",
127 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
128 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
129 | "engines": {
130 | "node": ">= 0.6"
131 | }
132 | },
133 | "node_modules/destroy": {
134 | "version": "1.0.4",
135 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
136 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
137 | },
138 | "node_modules/ee-first": {
139 | "version": "1.1.1",
140 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
141 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
142 | },
143 | "node_modules/encodeurl": {
144 | "version": "1.0.2",
145 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
146 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
147 | "engines": {
148 | "node": ">= 0.8"
149 | }
150 | },
151 | "node_modules/escape-html": {
152 | "version": "1.0.3",
153 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
154 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
155 | },
156 | "node_modules/etag": {
157 | "version": "1.8.1",
158 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
159 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
160 | "engines": {
161 | "node": ">= 0.6"
162 | }
163 | },
164 | "node_modules/express": {
165 | "version": "4.17.1",
166 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
167 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
168 | "dependencies": {
169 | "accepts": "~1.3.7",
170 | "array-flatten": "1.1.1",
171 | "body-parser": "1.19.0",
172 | "content-disposition": "0.5.3",
173 | "content-type": "~1.0.4",
174 | "cookie": "0.4.0",
175 | "cookie-signature": "1.0.6",
176 | "debug": "2.6.9",
177 | "depd": "~1.1.2",
178 | "encodeurl": "~1.0.2",
179 | "escape-html": "~1.0.3",
180 | "etag": "~1.8.1",
181 | "finalhandler": "~1.1.2",
182 | "fresh": "0.5.2",
183 | "merge-descriptors": "1.0.1",
184 | "methods": "~1.1.2",
185 | "on-finished": "~2.3.0",
186 | "parseurl": "~1.3.3",
187 | "path-to-regexp": "0.1.7",
188 | "proxy-addr": "~2.0.5",
189 | "qs": "6.7.0",
190 | "range-parser": "~1.2.1",
191 | "safe-buffer": "5.1.2",
192 | "send": "0.17.1",
193 | "serve-static": "1.14.1",
194 | "setprototypeof": "1.1.1",
195 | "statuses": "~1.5.0",
196 | "type-is": "~1.6.18",
197 | "utils-merge": "1.0.1",
198 | "vary": "~1.1.2"
199 | },
200 | "engines": {
201 | "node": ">= 0.10.0"
202 | }
203 | },
204 | "node_modules/finalhandler": {
205 | "version": "1.1.2",
206 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
207 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
208 | "dependencies": {
209 | "debug": "2.6.9",
210 | "encodeurl": "~1.0.2",
211 | "escape-html": "~1.0.3",
212 | "on-finished": "~2.3.0",
213 | "parseurl": "~1.3.3",
214 | "statuses": "~1.5.0",
215 | "unpipe": "~1.0.0"
216 | },
217 | "engines": {
218 | "node": ">= 0.8"
219 | }
220 | },
221 | "node_modules/forwarded": {
222 | "version": "0.1.2",
223 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
224 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
225 | "engines": {
226 | "node": ">= 0.6"
227 | }
228 | },
229 | "node_modules/fresh": {
230 | "version": "0.5.2",
231 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
232 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
233 | "engines": {
234 | "node": ">= 0.6"
235 | }
236 | },
237 | "node_modules/http-errors": {
238 | "version": "1.7.2",
239 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
240 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
241 | "dependencies": {
242 | "depd": "~1.1.2",
243 | "inherits": "2.0.3",
244 | "setprototypeof": "1.1.1",
245 | "statuses": ">= 1.5.0 < 2",
246 | "toidentifier": "1.0.0"
247 | },
248 | "engines": {
249 | "node": ">= 0.6"
250 | }
251 | },
252 | "node_modules/iconv-lite": {
253 | "version": "0.4.24",
254 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
255 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
256 | "dependencies": {
257 | "safer-buffer": ">= 2.1.2 < 3"
258 | },
259 | "engines": {
260 | "node": ">=0.10.0"
261 | }
262 | },
263 | "node_modules/inherits": {
264 | "version": "2.0.3",
265 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
266 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
267 | },
268 | "node_modules/ipaddr.js": {
269 | "version": "1.9.1",
270 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
271 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
272 | "engines": {
273 | "node": ">= 0.10"
274 | }
275 | },
276 | "node_modules/media-typer": {
277 | "version": "0.3.0",
278 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
279 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
280 | "engines": {
281 | "node": ">= 0.6"
282 | }
283 | },
284 | "node_modules/merge-descriptors": {
285 | "version": "1.0.1",
286 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
287 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
288 | },
289 | "node_modules/methods": {
290 | "version": "1.1.2",
291 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
292 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
293 | "engines": {
294 | "node": ">= 0.6"
295 | }
296 | },
297 | "node_modules/mime": {
298 | "version": "1.6.0",
299 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
300 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
301 | "bin": {
302 | "mime": "cli.js"
303 | },
304 | "engines": {
305 | "node": ">=4"
306 | }
307 | },
308 | "node_modules/mime-db": {
309 | "version": "1.44.0",
310 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
311 | "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
312 | "engines": {
313 | "node": ">= 0.6"
314 | }
315 | },
316 | "node_modules/mime-types": {
317 | "version": "2.1.27",
318 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
319 | "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
320 | "dependencies": {
321 | "mime-db": "1.44.0"
322 | },
323 | "engines": {
324 | "node": ">= 0.6"
325 | }
326 | },
327 | "node_modules/ms": {
328 | "version": "2.0.0",
329 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
330 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
331 | },
332 | "node_modules/negotiator": {
333 | "version": "0.6.2",
334 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
335 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
336 | "engines": {
337 | "node": ">= 0.6"
338 | }
339 | },
340 | "node_modules/object-assign": {
341 | "version": "4.1.1",
342 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
343 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
344 | "engines": {
345 | "node": ">=0.10.0"
346 | }
347 | },
348 | "node_modules/on-finished": {
349 | "version": "2.3.0",
350 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
351 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
352 | "dependencies": {
353 | "ee-first": "1.1.1"
354 | },
355 | "engines": {
356 | "node": ">= 0.8"
357 | }
358 | },
359 | "node_modules/parseurl": {
360 | "version": "1.3.3",
361 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
362 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
363 | "engines": {
364 | "node": ">= 0.8"
365 | }
366 | },
367 | "node_modules/path-to-regexp": {
368 | "version": "0.1.7",
369 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
370 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
371 | },
372 | "node_modules/proxy-addr": {
373 | "version": "2.0.6",
374 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
375 | "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
376 | "dependencies": {
377 | "forwarded": "~0.1.2",
378 | "ipaddr.js": "1.9.1"
379 | },
380 | "engines": {
381 | "node": ">= 0.10"
382 | }
383 | },
384 | "node_modules/qs": {
385 | "version": "6.7.0",
386 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
387 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
388 | "engines": {
389 | "node": ">=0.6"
390 | }
391 | },
392 | "node_modules/range-parser": {
393 | "version": "1.2.1",
394 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
395 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
396 | "engines": {
397 | "node": ">= 0.6"
398 | }
399 | },
400 | "node_modules/raw-body": {
401 | "version": "2.4.0",
402 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
403 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
404 | "dependencies": {
405 | "bytes": "3.1.0",
406 | "http-errors": "1.7.2",
407 | "iconv-lite": "0.4.24",
408 | "unpipe": "1.0.0"
409 | },
410 | "engines": {
411 | "node": ">= 0.8"
412 | }
413 | },
414 | "node_modules/redis": {
415 | "version": "3.0.2",
416 | "resolved": "https://registry.npmjs.org/redis/-/redis-3.0.2.tgz",
417 | "integrity": "sha512-PNhLCrjU6vKVuMOyFu7oSP296mwBkcE6lrAjruBYG5LgdSqtRBoVQIylrMyVZD/lkF24RSNNatzvYag6HRBHjQ==",
418 | "dependencies": {
419 | "denque": "^1.4.1",
420 | "redis-commands": "^1.5.0",
421 | "redis-errors": "^1.2.0",
422 | "redis-parser": "^3.0.0"
423 | },
424 | "engines": {
425 | "node": ">=6"
426 | }
427 | },
428 | "node_modules/redis-commands": {
429 | "version": "1.6.0",
430 | "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.6.0.tgz",
431 | "integrity": "sha512-2jnZ0IkjZxvguITjFTrGiLyzQZcTvaw8DAaCXxZq/dsHXz7KfMQ3OUJy7Tz9vnRtZRVz6VRCPDvruvU8Ts44wQ=="
432 | },
433 | "node_modules/redis-errors": {
434 | "version": "1.2.0",
435 | "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
436 | "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=",
437 | "engines": {
438 | "node": ">=4"
439 | }
440 | },
441 | "node_modules/redis-parser": {
442 | "version": "3.0.0",
443 | "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
444 | "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=",
445 | "dependencies": {
446 | "redis-errors": "^1.0.0"
447 | },
448 | "engines": {
449 | "node": ">=4"
450 | }
451 | },
452 | "node_modules/redis-redisearch": {
453 | "resolved": "git+ssh://git@github.com/stockholmux/node_redis-redisearch.git#61dc2229872cb13e7131f014e5319c50def07b80"
454 | },
455 | "node_modules/safe-buffer": {
456 | "version": "5.1.2",
457 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
458 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
459 | },
460 | "node_modules/safer-buffer": {
461 | "version": "2.1.2",
462 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
463 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
464 | },
465 | "node_modules/send": {
466 | "version": "0.17.1",
467 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
468 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
469 | "dependencies": {
470 | "debug": "2.6.9",
471 | "depd": "~1.1.2",
472 | "destroy": "~1.0.4",
473 | "encodeurl": "~1.0.2",
474 | "escape-html": "~1.0.3",
475 | "etag": "~1.8.1",
476 | "fresh": "0.5.2",
477 | "http-errors": "~1.7.2",
478 | "mime": "1.6.0",
479 | "ms": "2.1.1",
480 | "on-finished": "~2.3.0",
481 | "range-parser": "~1.2.1",
482 | "statuses": "~1.5.0"
483 | },
484 | "engines": {
485 | "node": ">= 0.8.0"
486 | }
487 | },
488 | "node_modules/send/node_modules/ms": {
489 | "version": "2.1.1",
490 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
491 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
492 | },
493 | "node_modules/serve-static": {
494 | "version": "1.14.1",
495 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
496 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
497 | "dependencies": {
498 | "encodeurl": "~1.0.2",
499 | "escape-html": "~1.0.3",
500 | "parseurl": "~1.3.3",
501 | "send": "0.17.1"
502 | },
503 | "engines": {
504 | "node": ">= 0.8.0"
505 | }
506 | },
507 | "node_modules/setprototypeof": {
508 | "version": "1.1.1",
509 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
510 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
511 | },
512 | "node_modules/statuses": {
513 | "version": "1.5.0",
514 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
515 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
516 | "engines": {
517 | "node": ">= 0.6"
518 | }
519 | },
520 | "node_modules/toidentifier": {
521 | "version": "1.0.0",
522 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
523 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
524 | "engines": {
525 | "node": ">=0.6"
526 | }
527 | },
528 | "node_modules/type-is": {
529 | "version": "1.6.18",
530 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
531 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
532 | "dependencies": {
533 | "media-typer": "0.3.0",
534 | "mime-types": "~2.1.24"
535 | },
536 | "engines": {
537 | "node": ">= 0.6"
538 | }
539 | },
540 | "node_modules/unpipe": {
541 | "version": "1.0.0",
542 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
543 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
544 | "engines": {
545 | "node": ">= 0.8"
546 | }
547 | },
548 | "node_modules/utils-merge": {
549 | "version": "1.0.1",
550 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
551 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
552 | "engines": {
553 | "node": ">= 0.4.0"
554 | }
555 | },
556 | "node_modules/vary": {
557 | "version": "1.1.2",
558 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
559 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
560 | "engines": {
561 | "node": ">= 0.8"
562 | }
563 | }
564 | },
565 | "dependencies": {
566 | "accepts": {
567 | "version": "1.3.7",
568 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
569 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
570 | "requires": {
571 | "mime-types": "~2.1.24",
572 | "negotiator": "0.6.2"
573 | }
574 | },
575 | "array-flatten": {
576 | "version": "1.1.1",
577 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
578 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
579 | },
580 | "body-parser": {
581 | "version": "1.19.0",
582 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
583 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
584 | "requires": {
585 | "bytes": "3.1.0",
586 | "content-type": "~1.0.4",
587 | "debug": "2.6.9",
588 | "depd": "~1.1.2",
589 | "http-errors": "1.7.2",
590 | "iconv-lite": "0.4.24",
591 | "on-finished": "~2.3.0",
592 | "qs": "6.7.0",
593 | "raw-body": "2.4.0",
594 | "type-is": "~1.6.17"
595 | }
596 | },
597 | "bytes": {
598 | "version": "3.1.0",
599 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
600 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
601 | },
602 | "content-disposition": {
603 | "version": "0.5.3",
604 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
605 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
606 | "requires": {
607 | "safe-buffer": "5.1.2"
608 | }
609 | },
610 | "content-type": {
611 | "version": "1.0.4",
612 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
613 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
614 | },
615 | "cookie": {
616 | "version": "0.4.0",
617 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
618 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
619 | },
620 | "cookie-signature": {
621 | "version": "1.0.6",
622 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
623 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
624 | },
625 | "cors": {
626 | "version": "2.8.5",
627 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
628 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
629 | "requires": {
630 | "object-assign": "^4",
631 | "vary": "^1"
632 | }
633 | },
634 | "debug": {
635 | "version": "2.6.9",
636 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
637 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
638 | "requires": {
639 | "ms": "2.0.0"
640 | }
641 | },
642 | "denque": {
643 | "version": "1.4.1",
644 | "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
645 | "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
646 | },
647 | "depd": {
648 | "version": "1.1.2",
649 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
650 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
651 | },
652 | "destroy": {
653 | "version": "1.0.4",
654 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
655 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
656 | },
657 | "ee-first": {
658 | "version": "1.1.1",
659 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
660 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
661 | },
662 | "encodeurl": {
663 | "version": "1.0.2",
664 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
665 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
666 | },
667 | "escape-html": {
668 | "version": "1.0.3",
669 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
670 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
671 | },
672 | "etag": {
673 | "version": "1.8.1",
674 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
675 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
676 | },
677 | "express": {
678 | "version": "4.17.1",
679 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
680 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
681 | "requires": {
682 | "accepts": "~1.3.7",
683 | "array-flatten": "1.1.1",
684 | "body-parser": "1.19.0",
685 | "content-disposition": "0.5.3",
686 | "content-type": "~1.0.4",
687 | "cookie": "0.4.0",
688 | "cookie-signature": "1.0.6",
689 | "debug": "2.6.9",
690 | "depd": "~1.1.2",
691 | "encodeurl": "~1.0.2",
692 | "escape-html": "~1.0.3",
693 | "etag": "~1.8.1",
694 | "finalhandler": "~1.1.2",
695 | "fresh": "0.5.2",
696 | "merge-descriptors": "1.0.1",
697 | "methods": "~1.1.2",
698 | "on-finished": "~2.3.0",
699 | "parseurl": "~1.3.3",
700 | "path-to-regexp": "0.1.7",
701 | "proxy-addr": "~2.0.5",
702 | "qs": "6.7.0",
703 | "range-parser": "~1.2.1",
704 | "safe-buffer": "5.1.2",
705 | "send": "0.17.1",
706 | "serve-static": "1.14.1",
707 | "setprototypeof": "1.1.1",
708 | "statuses": "~1.5.0",
709 | "type-is": "~1.6.18",
710 | "utils-merge": "1.0.1",
711 | "vary": "~1.1.2"
712 | }
713 | },
714 | "finalhandler": {
715 | "version": "1.1.2",
716 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
717 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
718 | "requires": {
719 | "debug": "2.6.9",
720 | "encodeurl": "~1.0.2",
721 | "escape-html": "~1.0.3",
722 | "on-finished": "~2.3.0",
723 | "parseurl": "~1.3.3",
724 | "statuses": "~1.5.0",
725 | "unpipe": "~1.0.0"
726 | }
727 | },
728 | "forwarded": {
729 | "version": "0.1.2",
730 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
731 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
732 | },
733 | "fresh": {
734 | "version": "0.5.2",
735 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
736 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
737 | },
738 | "http-errors": {
739 | "version": "1.7.2",
740 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
741 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
742 | "requires": {
743 | "depd": "~1.1.2",
744 | "inherits": "2.0.3",
745 | "setprototypeof": "1.1.1",
746 | "statuses": ">= 1.5.0 < 2",
747 | "toidentifier": "1.0.0"
748 | }
749 | },
750 | "iconv-lite": {
751 | "version": "0.4.24",
752 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
753 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
754 | "requires": {
755 | "safer-buffer": ">= 2.1.2 < 3"
756 | }
757 | },
758 | "inherits": {
759 | "version": "2.0.3",
760 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
761 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
762 | },
763 | "ipaddr.js": {
764 | "version": "1.9.1",
765 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
766 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
767 | },
768 | "media-typer": {
769 | "version": "0.3.0",
770 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
771 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
772 | },
773 | "merge-descriptors": {
774 | "version": "1.0.1",
775 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
776 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
777 | },
778 | "methods": {
779 | "version": "1.1.2",
780 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
781 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
782 | },
783 | "mime": {
784 | "version": "1.6.0",
785 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
786 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
787 | },
788 | "mime-db": {
789 | "version": "1.44.0",
790 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
791 | "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
792 | },
793 | "mime-types": {
794 | "version": "2.1.27",
795 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
796 | "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
797 | "requires": {
798 | "mime-db": "1.44.0"
799 | }
800 | },
801 | "ms": {
802 | "version": "2.0.0",
803 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
804 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
805 | },
806 | "negotiator": {
807 | "version": "0.6.2",
808 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
809 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
810 | },
811 | "object-assign": {
812 | "version": "4.1.1",
813 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
814 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
815 | },
816 | "on-finished": {
817 | "version": "2.3.0",
818 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
819 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
820 | "requires": {
821 | "ee-first": "1.1.1"
822 | }
823 | },
824 | "parseurl": {
825 | "version": "1.3.3",
826 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
827 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
828 | },
829 | "path-to-regexp": {
830 | "version": "0.1.7",
831 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
832 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
833 | },
834 | "proxy-addr": {
835 | "version": "2.0.6",
836 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
837 | "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
838 | "requires": {
839 | "forwarded": "~0.1.2",
840 | "ipaddr.js": "1.9.1"
841 | }
842 | },
843 | "qs": {
844 | "version": "6.7.0",
845 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
846 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
847 | },
848 | "range-parser": {
849 | "version": "1.2.1",
850 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
851 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
852 | },
853 | "raw-body": {
854 | "version": "2.4.0",
855 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
856 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
857 | "requires": {
858 | "bytes": "3.1.0",
859 | "http-errors": "1.7.2",
860 | "iconv-lite": "0.4.24",
861 | "unpipe": "1.0.0"
862 | }
863 | },
864 | "redis": {
865 | "version": "3.0.2",
866 | "resolved": "https://registry.npmjs.org/redis/-/redis-3.0.2.tgz",
867 | "integrity": "sha512-PNhLCrjU6vKVuMOyFu7oSP296mwBkcE6lrAjruBYG5LgdSqtRBoVQIylrMyVZD/lkF24RSNNatzvYag6HRBHjQ==",
868 | "requires": {
869 | "denque": "^1.4.1",
870 | "redis-commands": "^1.5.0",
871 | "redis-errors": "^1.2.0",
872 | "redis-parser": "^3.0.0"
873 | }
874 | },
875 | "redis-commands": {
876 | "version": "1.6.0",
877 | "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.6.0.tgz",
878 | "integrity": "sha512-2jnZ0IkjZxvguITjFTrGiLyzQZcTvaw8DAaCXxZq/dsHXz7KfMQ3OUJy7Tz9vnRtZRVz6VRCPDvruvU8Ts44wQ=="
879 | },
880 | "redis-errors": {
881 | "version": "1.2.0",
882 | "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
883 | "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60="
884 | },
885 | "redis-parser": {
886 | "version": "3.0.0",
887 | "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
888 | "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=",
889 | "requires": {
890 | "redis-errors": "^1.0.0"
891 | }
892 | },
893 | "redis-redisearch": {
894 | "version": "git+ssh://git@github.com/stockholmux/node_redis-redisearch.git#61dc2229872cb13e7131f014e5319c50def07b80",
895 | "from": "redis-redisearch@stockholmux/node_redis-redisearch"
896 | },
897 | "safe-buffer": {
898 | "version": "5.1.2",
899 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
900 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
901 | },
902 | "safer-buffer": {
903 | "version": "2.1.2",
904 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
905 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
906 | },
907 | "send": {
908 | "version": "0.17.1",
909 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
910 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
911 | "requires": {
912 | "debug": "2.6.9",
913 | "depd": "~1.1.2",
914 | "destroy": "~1.0.4",
915 | "encodeurl": "~1.0.2",
916 | "escape-html": "~1.0.3",
917 | "etag": "~1.8.1",
918 | "fresh": "0.5.2",
919 | "http-errors": "~1.7.2",
920 | "mime": "1.6.0",
921 | "ms": "2.1.1",
922 | "on-finished": "~2.3.0",
923 | "range-parser": "~1.2.1",
924 | "statuses": "~1.5.0"
925 | },
926 | "dependencies": {
927 | "ms": {
928 | "version": "2.1.1",
929 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
930 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
931 | }
932 | }
933 | },
934 | "serve-static": {
935 | "version": "1.14.1",
936 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
937 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
938 | "requires": {
939 | "encodeurl": "~1.0.2",
940 | "escape-html": "~1.0.3",
941 | "parseurl": "~1.3.3",
942 | "send": "0.17.1"
943 | }
944 | },
945 | "setprototypeof": {
946 | "version": "1.1.1",
947 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
948 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
949 | },
950 | "statuses": {
951 | "version": "1.5.0",
952 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
953 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
954 | },
955 | "toidentifier": {
956 | "version": "1.0.0",
957 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
958 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
959 | },
960 | "type-is": {
961 | "version": "1.6.18",
962 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
963 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
964 | "requires": {
965 | "media-typer": "0.3.0",
966 | "mime-types": "~2.1.24"
967 | }
968 | },
969 | "unpipe": {
970 | "version": "1.0.0",
971 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
972 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
973 | },
974 | "utils-merge": {
975 | "version": "1.0.1",
976 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
977 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
978 | },
979 | "vary": {
980 | "version": "1.1.2",
981 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
982 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
983 | }
984 | }
985 | }
986 |
--------------------------------------------------------------------------------