diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..87a52e6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +# EditorConfig helps maintain consistent coding styles between different editors and IDEs + +[*] +indent_style = space +indent_size = 4 +# IntelliJ/JetBrains continuation indent (e.g., wrapped lines) +ij_continuation_indent_size = 8 + +ij_any_keep_line_breaks = true + +# Keep trailing whitespace and EOL settings untouched to minimize changes \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2065bc --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/.run/SolrMcpServerHttp.run.xml b/.run/SolrMcpServerHttp.run.xml new file mode 100644 index 0000000..8038646 --- /dev/null +++ b/.run/SolrMcpServerHttp.run.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/.run/SolrMcpServerStdio.run.xml b/.run/SolrMcpServerStdio.run.xml new file mode 100644 index 0000000..ec78c9f --- /dev/null +++ b/.run/SolrMcpServerStdio.run.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 534e44e..0000000 --- a/LICENSE.txt +++ /dev/null @@ -1,226 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -========================================================================== -The following license applies to the JQuery JavaScript library --------------------------------------------------------------------------- -Copyright (c) 2010 John Resig, http://jquery.com/ - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/README.md b/README.md new file mode 100644 index 0000000..0ce64ed --- /dev/null +++ b/README.md @@ -0,0 +1,461 @@ +# Solr MCP Server + +A Spring AI Model Context Protocol (MCP) server that provides tools for interacting with Apache Solr. This server +enables AI assistants like Claude to search, index, and manage Solr collections through the MCP protocol. + +## Overview + +This project provides a set of tools that allow AI assistants to interact with Apache Solr, a powerful open-source +search platform. By implementing the Spring AI MCP protocol, these tools can be used by any MCP-compatible client, +including Claude Desktop. The project uses SolrJ, the official Java client for Solr, to communicate with Solr instances. + +The server provides the following capabilities: + +- Search Solr collections with advanced query options +- Index documents into Solr collections +- Manage and monitor Solr collections +- Retrieve and analyze Solr schema information + +### Transport Profiles + +The server supports two transport modes: + +- **STDIO (Standard Input/Output)** - Recommended for local development and production use with Claude Desktop. This is + the default and most secure option for local deployments. +- **HTTP (Streamable HTTP)** - For testing with MCP Inspector and remote deployments. ⚠️ **Note:** HTTP + mode is inherently insecure without additional security measures (see Security Considerations below). + +## Prerequisites + +- Java 25 or higher +- Docker and Docker Compose (for running Solr) +- Gradle 9.1.0+ (wrapper included in project) + +## Installation and Setup + +### 1. Clone the repository + +```bash +git clone https://github.com/yourusername/solr-mcp-server.git +cd solr-mcp-server +``` + +### 2. Start Solr using Docker Compose + +```bash +docker-compose up -d +``` + +This will start a Solr instance in SolrCloud mode with ZooKeeper and create two sample collections: + +- `books` - A collection with sample book data +- `films` - A collection with sample film data + +### 3. Build the Project + +This project uses Gradle with version catalogs for dependency management. All dependencies and their versions are +centrally managed in `gradle/libs.versions.toml`. + +```bash +# Build the project and run tests +./gradlew build + +# Build without tests (faster) +./gradlew assemble + +# Clean and rebuild +./gradlew clean build +``` + +The build produces two JAR files in `build/libs/`: + +- `solr-mcp-server-0.0.1-SNAPSHOT.jar` - Executable JAR with all dependencies (fat JAR) +- `solr-mcp-server-0.0.1-SNAPSHOT-plain.jar` - Plain JAR without dependencies + +## Project Structure + +The codebase follows a clean, modular architecture organized by functionality: + +``` +src/main/java/org/apache/solr/mcp/server/ +├── Main.java # Application entry point +├── config/ # Configuration classes +│ ├── SolrConfig.java # Solr client bean configuration +│ └── SolrConfigurationProperties.java # Solr connection properties +├── search/ # Search functionality +│ ├── SearchService.java # MCP tool for searching Solr +│ └── SearchResponse.java # Search result DTOs +├── indexing/ # Document indexing functionality +│ ├── IndexingService.java # MCP tool for indexing documents +│ └── documentcreator/ # Document format parsers +│ ├── IndexingDocumentCreator.java # Interface for document creators +│ ├── JsonDocumentCreator.java # JSON document parser +│ ├── CsvDocumentCreator.java # CSV document parser +│ ├── XmlDocumentCreator.java # XML document parser +│ ├── SolrDocumentCreator.java # Factory for document creators +│ ├── FieldNameSanitizer.java # Field name sanitization utility +│ └── DocumentProcessingException.java # Indexing exceptions +└── metadata/ # Collection management functionality + ├── CollectionService.java # MCP tools for collection operations + ├── SchemaService.java # MCP tool for schema retrieval + ├── CollectionUtils.java # Collection utility methods + └── Dtos.java # Collection-related DTOs (records) +``` + +### Key Components + +- **MCP Tools**: Service classes annotated with `@McpTool` expose functionality to AI assistants + - `SearchService` - Search queries with filtering, faceting, and pagination + - `IndexingService` - Document indexing with support for JSON, CSV, and XML formats + - `CollectionService` - Collection management (list, stats, health checks) + - `SchemaService` - Schema introspection + +- **Configuration**: Spring Boot configuration using properties files + - `application.properties` - Default configuration + - `application-stdio.properties` - STDIO transport profile + - `application-http.properties` - HTTP transport profile + +- **Document Creators**: Strategy pattern implementation for parsing different document formats + - Automatically sanitizes field names to comply with Solr schema requirements + - Supports nested JSON structures and multi-valued fields + +- **DTOs**: Java records for immutable data transfer objects (removed Lombok dependency) + +## Available Tools + +The server provides the following tools that can be used by MCP clients: + +### 1. Search + +Search a Solr collection with advanced query options. + +``` +Tool: Search +Description: Search specified Solr collection with query, optional filters, facets, sorting, and pagination. +Parameters: + - collection: Solr collection to query + - query: Solr q parameter (defaults to "*:*" if not specified) + - filterQueries: Solr fq parameter (optional) + - facetFields: Solr facet fields (optional) + - sortClauses: Solr sort parameter (optional) + - start: Starting offset for pagination (optional) + - rows: Number of rows to return (optional) +``` + +### 2. Index Documents + +Index JSON documents into a Solr collection. + +``` +Tool: index_documents +Description: Index documents from JSON string into Solr collection +Parameters: + - collection: Solr collection to index into + - json: JSON string containing documents to index +``` + +### 3. List Collections + +List all available Solr collections. + +``` +Tool: listCollections +Description: List solr collections +Parameters: None +``` + +### 4. Get Collection Stats + +Get detailed statistics and metrics for a Solr collection. + +``` +Tool: getCollectionStats +Description: Get stats/metrics on a Solr collection +Parameters: + - collection: Name of the collection +``` + +### 5. Check Collection Health + +Check the health status of a Solr collection. + +``` +Tool: checkHealth +Description: Check health of a Solr collection +Parameters: + - collection: Name of the collection +``` + +### 6. Get Schema + +Retrieve the schema for a Solr collection. + +``` +Tool: getSchema +Description: Get schema for a Solr collection +Parameters: + - collection: Name of the collection +``` + +## Adding to Claude Desktop + +To add this MCP server to Claude Desktop: + +1. Build the project as a standalone JAR: + +```bash +./gradlew build +``` + +2. In Claude Desktop, go to Settings > Developer > Edit Config + +3. Add the following configuration to your MCP settings: + +```json +{ + "mcpServers": { + "solr-search-mcp": { + "command": "java", + "args": [ + "-jar", + "/absolute/path/to/solr-mcp-server/build/libs/solr-mcp-server-0.0.1-SNAPSHOT.jar" + ], + "env": { + "SOLR_URL": "http://localhost:8983/solr/", + "PROFILES": "stdio" + } + } + } +} +``` + +**Note:** Replace `/absolute/path/to/solr-mcp-server` with the actual path to your project directory. + +### 4. Restart Claude Desktop & Invoke + +![claude-stdio.png](images/claude-stdio.png) + +## Testing with MCP Inspector + +For development and testing, you can use the [MCP Inspector](https://github.com/modelcontextprotocol/inspector): + +```bash +# Install the MCP Inspector (requires Node.js) +➜ ~ npx @modelcontextprotocol/inspector + +Starting MCP inspector... +⚙️ Proxy server listening on localhost:6277 +🔑 Session token: 12345 + Use this token to authenticate requests or set DANGEROUSLY_OMIT_AUTH=true to disable auth + +🚀 MCP Inspector is up and running at: + http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=12345 + +🌐 Opening browser... +``` + +This provides a web interface to test MCP tools interactively. +![mcp-inspector-stdio.png](images/mcp-inspector-stdio.png) + +# HTTP Mode + +![mcp-inspector-http.png](images/mcp-inspector-http.png) + +```shell +./gradlew bootRun --args='--spring.profiles.active=http' +``` + +## Tools Usage Examples + +Here are some examples of how to use the tools from an MCP client like Claude: + +### Searching for Books + +``` +I need to search for fantasy books in the Solr collection. Can you help me? +``` + +Claude can use the Search tool to query the books collection: + +``` +I'll search for fantasy books in the Solr collection. + +Using the Search tool with: +- collection: books +- query: genre_s:fantasy +- rows: 5 + +Here are the fantasy books I found: +1. "A Game of Thrones" by George R.R. Martin +2. "A Clash of Kings" by George R.R. Martin +... +``` + +### Indexing New Documents + +``` +I have some new book data I'd like to add to Solr. Can you help me index it? +``` + +Claude can use the index_documents tool: + +``` +I'll help you index that book data into Solr. + +Using the index_documents tool with: +- collection: books +- json: [{"id":"123456789","name":["The New Book"],"author":["Jane Author"],"genre_s":"mystery","price":[12.99]}] + +The document has been successfully indexed into the books collection. +``` + +### Listing Collections + +``` +What Solr collections are available in the system? +``` + +Claude can use the listCollections tool: + +``` +I'll check what Solr collections are available. + +Using the listCollections tool. + +The following collections are available: +1. books +2. films +``` + +### Getting Collection Statistics + +``` +Can you tell me more about the 'books' collection? I'd like to know its size and other metrics. +``` + +Claude can use the getCollectionStats tool: + +``` +I'll get statistics for the 'books' collection. + +Using the getCollectionStats tool with: +- collection: books + +Here are the statistics for the 'books' collection: +- Number of documents: 1,245 +- Segment count: 5 +- Query performance: + - Average query time: 12ms + - Cache hit ratio: 0.85 +- Handler statistics: + - Select handler requests: 1,532 + - Update handler requests: 245 +``` + +### Checking Collection Health + +``` +Is the 'films' collection healthy and responding properly? +``` + +Claude can use the checkHealth tool: + +``` +I'll check the health of the 'films' collection. + +Using the checkHealth tool with: +- collection: films + +Health status: +- Healthy: Yes +- Response time: 8ms +- Total documents: 532 +- Last checked: 2023-06-15 14:32:45 +``` + +### Retrieving Schema Information + +``` +What fields are defined in the 'books' collection schema? +``` + +Claude can use the getSchema tool: + +``` +I'll retrieve the schema for the 'books' collection. + +Using the getSchema tool with: +- collection: books + +The 'books' collection has the following fields: +- id (string): Unique identifier +- name (text_general): Book title +- author (text_general): Book author +- genre_s (string): Genre +- price (float): Book price +- in_stock_b (boolean): Whether the book is in stock +- publish_date (date): Publication date +``` + +## Security Considerations + +### STDIO Transport Security + +STDIO transport is the recommended option for local deployments because: + +- Communication occurs within the same machine through process pipes +- No network exposure or open ports +- OS-level process isolation provides security boundaries +- Credentials are not exposed over the network + +### HTTP Transport Security Risks + +⚠️ **Warning**: The current HTTP implementation is **insecure** for production use without additional security +measures. + +HTTP transport has the following security vulnerabilities when deployed without authentication: + +1. **No Authentication or Authorization**: By default, the HTTP endpoints are publicly accessible without any + authentication mechanism +2. **No Transport Encryption**: HTTP traffic is unencrypted and can be intercepted (use HTTPS in production) +3. **No Origin Validation**: Without proper origin header validation, the server is vulnerable to DNS rebinding attacks +4. **Network Exposure**: Unlike STDIO, HTTP endpoints are exposed over the network and accessible to any client that can + reach the server + +### Securing HTTP Deployments + +If you need to deploy the MCP server with HTTP transport for remote access, you **must** implement security +controls: + +1. **Use HTTPS**: Always use TLS/SSL encryption for production deployments +2. **Implement OAuth2 Authentication**: Follow + the [Spring AI MCP OAuth2 guide](https://spring.io/blog/2025/04/02/mcp-server-oauth2/) to add authentication +3. **Validate Origin Headers**: Implement origin header validation to prevent DNS rebinding attacks +4. **Network Isolation**: Deploy behind a firewall or VPN, restricting access to trusted networks +5. **Use API Gateways**: Consider deploying behind an API gateway with authentication and rate limiting + +### Recommendation + +- **Local development/testing**: Use HTTP mode for testing with MCP Inspector, but only on localhost +- **Claude Desktop integration**: Always use STDIO mode +- **Production remote deployments**: Only use HTTP with OAuth2 authentication, HTTPS, and proper network security + controls + +## Troubleshooting + +If you encounter issues: + +1. Ensure Solr is running and accessible. By default, the server connects to http://localhost:8983/solr/, but you can + set the `SOLR_URL` environment variable to point to a different Solr instance. +2. Check the logs for any error messages +3. Verify that the collections exist using the Solr Admin UI +4. If using HTTP mode, ensure the server is running on the expected port (default: 8080) +5. For STDIO mode with Claude Desktop, verify the JAR path is absolute and correct in the configuration + +## License + +This project is licensed under the Apache License 2.0. + +## Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..363308b --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,101 @@ +import net.ltgt.gradle.errorprone.errorprone + +plugins { + java + alias(libs.plugins.spring.boot) + alias(libs.plugins.spring.dependency.management) + jacoco + alias(libs.plugins.errorprone) + alias(libs.plugins.spotless) +} + +group = "org.apache.solr" +version = "0.0.1-SNAPSHOT" + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(25) + } +} + +configurations { + compileOnly { + extendsFrom(configurations.annotationProcessor.get()) + } +} + +repositories { + mavenCentral() +} + +dependencies { + + developmentOnly(libs.bundles.spring.boot.dev) + + implementation(libs.spring.boot.starter.web) + implementation(libs.spring.boot.starter.actuator) + implementation(libs.spring.ai.starter.mcp.server.webmvc) + implementation(libs.solr.solrj) { + exclude(group = "org.apache.httpcomponents") + } + implementation(libs.commons.csv) + // JSpecify for nullability annotations + implementation(libs.jspecify) + + // Error Prone and NullAway for null safety analysis + errorprone(libs.errorprone.core) + errorprone(libs.nullaway) + + testImplementation(libs.bundles.test) + testRuntimeOnly(libs.junit.platform.launcher) +} + +dependencyManagement { + imports { + mavenBom("org.springframework.ai:spring-ai-bom:${libs.versions.spring.ai.get()}") + // Align Jetty family to 10.x compatible with SolrJ 9.x + mavenBom("org.eclipse.jetty:jetty-bom:${libs.versions.jetty.get()}") + } +} + +tasks.withType { + useJUnitPlatform() + finalizedBy(tasks.jacocoTestReport) +} + +tasks.jacocoTestReport { + dependsOn(tasks.test) + reports { + xml.required.set(true) + html.required.set(true) + csv.required.set(false) + } +} + +tasks.withType().configureEach { + options.errorprone { + disableAllChecks.set(true) // Other error prone checks are disabled + option("NullAway:OnlyNullMarked", "true") // Enable nullness checks only in null-marked code + error("NullAway") // bump checks from warnings (default) to errors + } +} + +tasks.build { + dependsOn(tasks.spotlessApply) +} + +spotless { + java { + target("src/**/*.java") + googleJavaFormat().aosp().reflowLongStrings() + removeUnusedImports() + trimTrailingWhitespace() + endWithNewline() + importOrder() + formatAnnotations() + } + kotlinGradle { + target("*.gradle.kts") + ktlint() + } +} diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..ed63f48 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,28 @@ +services: + solr: + image: solr:9-slim + ports: + - "8983:8983" + networks: [ search ] + environment: + ZK_HOST: "zoo:2181" + SOLR_HEAP: "1g" + depends_on: [ zoo ] + volumes: + - data:/var/solr + - ./mydata:/mydata + - ./init-solr.sh:/init-solr.sh + command: [ "bash", "/init-solr.sh" ] + + zoo: + image: zookeeper:3.9 + networks: [ search ] + environment: + ZOO_4LW_COMMANDS_WHITELIST: "mntr,conf,ruok" + +volumes: + data: + +networks: + search: + driver: bridge diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..e3ec063 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,85 @@ +[versions] +# Build plugins +spring-boot = "3.5.6" +spring-dependency-management = "1.1.7" +sonarqube = "6.2.0.5505" +errorprone-plugin = "4.2.0" +spotless = "7.0.2" + +# Main dependencies +spring-ai = "1.1.0-M3" +solr = "9.8.1" +commons-csv = "1.10.0" +jspecify = "1.0.0" + +# Error Prone and analysis tools +errorprone-core = "2.38.0" +nullaway = "0.12.7" + +# Jetty BOM version +jetty = "10.0.22" + +# Test dependencies +testcontainers = "1.21.3" + +[libraries] +# Spring +spring-boot-starter-web = { module = "org.springframework.boot:spring-boot-starter-web" } +spring-boot-starter-actuator = { module = "org.springframework.boot:spring-boot-starter-actuator" } +spring-boot-docker-compose = { module = "org.springframework.boot:spring-boot-docker-compose" } +spring-boot-starter-test = { module = "org.springframework.boot:spring-boot-starter-test" } +spring-boot-testcontainers = { module = "org.springframework.boot:spring-boot-testcontainers" } +# Spring AI +spring-ai-starter-mcp-server-webmvc = { module = "org.springframework.ai:spring-ai-starter-mcp-server-webmvc" } +spring-ai-starter-mcp-client = { module = "org.springframework.ai:spring-ai-starter-mcp-client" } +spring-ai-spring-boot-docker-compose = { module = "org.springframework.ai:spring-ai-spring-boot-docker-compose" } +spring-ai-spring-boot-testcontainers = { module = "org.springframework.ai:spring-ai-spring-boot-testcontainers" } + +# Solr +solr-solrj = { module = "org.apache.solr:solr-solrj", version.ref = "solr" } + +# Apache Commons +commons-csv = { module = "org.apache.commons:commons-csv", version.ref = "commons-csv" } + +# Null safety +jspecify = { module = "org.jspecify:jspecify", version.ref = "jspecify" } + +# Error Prone +errorprone-core = { module = "com.google.errorprone:error_prone_core", version.ref = "errorprone-core" } +nullaway = { module = "com.uber.nullaway:nullaway", version.ref = "nullaway" } + +# Test dependencies +testcontainers-junit-jupiter = { module = "org.testcontainers:junit-jupiter" } +testcontainers-solr = { module = "org.testcontainers:solr", version.ref = "testcontainers" } +junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" } + +[bundles] +spring-ai-mcp = [ + "spring-boot-starter-web", + "spring-ai-starter-mcp-server-webmvc" +] + +spring-boot-dev = [ + "spring-boot-docker-compose", + "spring-ai-spring-boot-docker-compose" +] + +test = [ + "spring-boot-starter-test", + "spring-boot-testcontainers", + "spring-ai-spring-boot-testcontainers", + "testcontainers-junit-jupiter", + "testcontainers-solr", + "spring-ai-starter-mcp-client" +] + +errorprone = [ + "errorprone-core", + "nullaway" +] + +[plugins] +spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" } +spring-dependency-management = { id = "io.spring.dependency-management", version.ref = "spring-dependency-management" } +errorprone = { id = "net.ltgt.errorprone", version.ref = "errorprone-plugin" } +spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..f8e1ee3 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..a35649f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-all.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..23d15a9 --- /dev/null +++ b/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH="\\\"\\\"" + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..db3a6ac --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH= + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/images/claude-stdio.png b/images/claude-stdio.png new file mode 100644 index 0000000..c9b67f6 Binary files /dev/null and b/images/claude-stdio.png differ diff --git a/images/mcp-inspector-http.png b/images/mcp-inspector-http.png new file mode 100644 index 0000000..df01ac8 Binary files /dev/null and b/images/mcp-inspector-http.png differ diff --git a/images/mcp-inspector-stdio.png b/images/mcp-inspector-stdio.png new file mode 100644 index 0000000..cc5fd8c Binary files /dev/null and b/images/mcp-inspector-stdio.png differ diff --git a/init-solr.sh b/init-solr.sh new file mode 100644 index 0000000..cc0cbee --- /dev/null +++ b/init-solr.sh @@ -0,0 +1,80 @@ +#!/bin/bash +set -e + +# Ensure mydata directory exists +mkdir -p /mydata + +## Download books.csv if not already present +#if [ ! -f /mydata/books.csv ]; then +# wget -O /mydata/books.csv https://raw.githubusercontent.com/apache/solr/main/solr/example/exampledocs/books.csv +#fi + +# Download films.json if not already present +if [ ! -f /mydata/films.json ]; then + wget -O /mydata/films.json https://raw.githubusercontent.com/apache/solr/refs/heads/main/solr/example/films/films.json +fi + +# Start Solr in background +/opt/solr/bin/solr start -c -z zoo:2181 + +# Wait for Solr to be up +until curl -s http://localhost:8983/solr/ > /dev/null; do + echo "Waiting for Solr to start..." + sleep 2 +done + +# Wait for ZooKeeper to be fully ready for SolrCloud operations +echo "Waiting for ZooKeeper to be ready for SolrCloud operations..." +sleep 10 + +# Wait for cluster state to be ready +until curl -s "http://localhost:8983/solr/admin/collections?action=CLUSTERSTATUS" | grep -q '"responseHeader"'; do + echo "Waiting for SolrCloud cluster to be ready..." + sleep 2 +done + +# Function to create collection if it doesn't exist +create_collection_if_not_exists() { + local collection_name=$1 + if ! curl -s "http://localhost:8983/solr/admin/collections?action=LIST" | grep -q "\"$collection_name\""; then + echo "Creating $collection_name collection..." + /opt/solr/bin/solr create -c "$collection_name" -n _default || { + echo "First attempt failed, retrying collection creation..." + sleep 5 + /opt/solr/bin/solr create -c "$collection_name" -n _default || { + echo "Collection creation failed twice, but continuing..." + } + } + else + echo "$collection_name collection already exists, skipping creation." + fi +} + +# Create collections +create_collection_if_not_exists "books" +create_collection_if_not_exists "films" + +# Configure films schema +curl -X POST -H 'Content-type:application/json' --data-binary '{ + "add-field": { + "name":"name", + "type":"text_general", + "multiValued":false, + "stored":true + }, + "add-field": { + "name":"initial_release_date", + "type":"pdate", + "stored":true + } +}' http://localhost:8983/solr/films/schema + +## Post the books.csv data +#/opt/solr/bin/solr post -c books /mydata/books.csv + +# Post the films.json data +/opt/solr/bin/solr post -c films /mydata/films.json + +# Stop background Solr and run in foreground +/opt/solr/bin/solr stop +exec /opt/solr/bin/solr start -c -z zoo:2181 -f diff --git a/mydata/books.csv b/mydata/books.csv new file mode 100644 index 0000000..8ccecbb --- /dev/null +++ b/mydata/books.csv @@ -0,0 +1,11 @@ +id,cat,name,price,inStock,author,series_t,sequence_i,genre_s +0553573403,book,A Game of Thrones,7.99,true,George R.R. Martin,"A Song of Ice and Fire",1,fantasy +0553579908,book,A Clash of Kings,7.99,true,George R.R. Martin,"A Song of Ice and Fire",2,fantasy +055357342X,book,A Storm of Swords,7.99,true,George R.R. Martin,"A Song of Ice and Fire",3,fantasy +0553293354,book,Foundation,7.99,true,Isaac Asimov,Foundation Novels,1,scifi +0812521390,book,The Black Company,6.99,false,Glen Cook,The Chronicles of The Black Company,1,fantasy +0812550706,book,Ender's Game,6.99,true,Orson Scott Card,Ender,1,scifi +0441385532,book,Jhereg,7.95,false,Steven Brust,Vlad Taltos,1,fantasy +0380014300,book,Nine Princes In Amber,6.99,true,Roger Zelazny,the Chronicles of Amber,1,fantasy +0805080481,book,The Book of Three,5.99,true,Lloyd Alexander,The Chronicles of Prydain,1,fantasy +080508049X,book,The Black Cauldron,5.99,true,Lloyd Alexander,The Chronicles of Prydain,2,fantasy diff --git a/mydata/books.xml b/mydata/books.xml new file mode 100644 index 0000000..a137173 --- /dev/null +++ b/mydata/books.xml @@ -0,0 +1,116 @@ + + + + book + A Game of Thrones + 7.99 + true + + George R.R. Martin + george@example.com + + A Song of Ice and Fire + 1 + fantasy + + epic fantasy + medieval + political intrigue + + + + + book + A Clash of Kings + 7.99 + true + + George R.R. Martin + george@example.com + + A Song of Ice and Fire + 2 + fantasy + + epic fantasy + war + dragons + + + + + book + A Storm of Swords + 7.99 + true + + George R.R. Martin + george@example.com + + A Song of Ice and Fire + 3 + fantasy + + epic fantasy + betrayal + magic + + + + + book + Foundation + 7.99 + true + + Isaac Asimov + isaac@example.com + + Foundation Novels + 1 + scifi + + space opera + psychohistory + galactic empire + + + + + book + The Black Company + 6.99 + false + + Glen Cook + glen@example.com + + The Chronicles of The Black Company + 1 + fantasy + + military fantasy + dark fantasy + mercenaries + + + + + book + Ender's Game + 6.99 + true + + Orson Scott Card + orson@example.com + + Ender + 1 + scifi + + space warfare + coming of age + aliens + + + \ No newline at end of file diff --git a/mydata/films.json b/mydata/films.json new file mode 100644 index 0000000..53715ab --- /dev/null +++ b/mydata/films.json @@ -0,0 +1,29030 @@ +[ + { + "id": "/en/45_2006", + "directed_by": [ + "Gary Lennon" + ], + "initial_release_date": "2006-11-30", + "genre": [ + "Black comedy", + "Thriller", + "Psychological thriller", + "Indie film", + "Action Film", + "Crime Thriller", + "Crime Fiction", + "Drama" + ], + "name": ".45", + "film_vector": [ + -0.5178138017654419, + -0.2626153230667114, + -0.3770933747291565, + -0.006518090143799782, + -0.09938755631446838, + -0.21104438602924347, + 0.07726429402828217, + -0.15192025899887085, + 0.040976863354444504, + -0.10118144005537033 + ] + }, + { + "id": "/en/9_2005", + "directed_by": [ + "Shane Acker" + ], + "initial_release_date": "2005-04-21", + "genre": [ + "Computer Animation", + "Animation", + "Apocalyptic and post-apocalyptic fiction", + "Science Fiction", + "Short Film", + "Thriller", + "Fantasy" + ], + "name": "9", + "film_vector": [ + -0.4619390666484833, + -0.08695199340581894, + 0.045319393277168274, + 0.1738782525062561, + -0.3030739724636078, + -0.0439307801425457, + -0.04721732810139656, + 0.008997736498713493, + 0.1922629028558731, + -0.05279424041509628 + ] + }, + { + "id": "/en/69_2004", + "directed_by": [ + "Lee Sang-il" + ], + "initial_release_date": "2004-07-10", + "genre": [ + "Japanese Movies", + "Drama" + ], + "name": "69", + "film_vector": [ + -0.2955506145954132, + 0.09657415002584457, + -0.07419842481613159, + 0.23438382148742676, + 0.07551798224449158, + -0.08758169412612915, + 0.049781735986471176, + -0.00844656303524971, + 0.0630975067615509, + -0.22167503833770752 + ] + }, + { + "id": "/en/300_2007", + "directed_by": [ + "Zack Snyder" + ], + "initial_release_date": "2006-12-09", + "genre": [ + "Epic film", + "Adventure Film", + "Fantasy", + "Action Film", + "Historical fiction", + "War film", + "Superhero movie", + "Historical Epic" + ], + "name": "300", + "film_vector": [ + -0.48956114053726196, + 0.01498105563223362, + -0.11208540201187134, + 0.23499861359596252, + -0.1889166533946991, + -0.2565075755119324, + -0.283454567193985, + 0.09469281882047653, + -0.20055626332759857, + -0.1315811425447464 + ] + }, + { + "id": "/en/2046_2004", + "directed_by": [ + "Wong Kar-wai" + ], + "initial_release_date": "2004-05-20", + "genre": [ + "Romance Film", + "Fantasy", + "Science Fiction", + "Drama" + ], + "name": "2046", + "film_vector": [ + -0.45051273703575134, + 0.005097106099128723, + -0.23324492573738098, + 0.1513277292251587, + -0.0026537850499153137, + 4.404550418257713e-05, + -0.18614956736564636, + -0.11424130201339722, + 0.08597377687692642, + -0.052943550050258636 + ] + }, + { + "id": "/en/quien_es_el_senor_lopez", + "directed_by": [ + "Luis Mandoki" + ], + "genre": [ + "Documentary film" + ], + "name": "\u00bfQui\u00e9n es el se\u00f1or L\u00f3pez?", + "film_vector": [ + 0.07133805751800537, + 0.009939568117260933, + 0.03740257769823074, + -0.06827103346586227, + 0.06991000473499298, + -0.34970977902412415, + -0.08846394717693329, + -0.04976935684680939, + 0.1357077658176422, + -0.15086549520492554 + ] + }, + { + "id": "/en/weird_al_yankovic_the_ultimate_video_collection", + "directed_by": [ + "Jay Levey", + "\"Weird Al\" Yankovic" + ], + "initial_release_date": "2003-11-04", + "genre": [ + "Music video", + "Parody" + ], + "name": "\"Weird Al\" Yankovic: The Ultimate Video Collection", + "film_vector": [ + 0.2234971821308136, + 0.05691061168909073, + -0.09928493946790695, + 0.033965736627578735, + -0.17690393328666687, + -0.2965765595436096, + 0.24921706318855286, + 0.023038793355226517, + 0.1363428831100464, + 0.13869339227676392 + ] + }, + { + "id": "/en/15_park_avenue", + "directed_by": [ + "Aparna Sen" + ], + "initial_release_date": "2005-10-27", + "genre": [ + "Art film", + "Romance Film", + "Musical", + "Drama", + "Musical Drama" + ], + "name": "15 Park Avenue", + "film_vector": [ + -0.23868215084075928, + 0.06881184875965118, + -0.3884967565536499, + -0.006916673853993416, + 0.06198021024465561, + -0.16578459739685059, + -0.14860263466835022, + 0.0012244954705238342, + 0.18506643176078796, + -0.11147791147232056 + ] + }, + { + "id": "/en/2_fast_2_furious", + "directed_by": [ + "John Singleton" + ], + "initial_release_date": "2003-06-03", + "genre": [ + "Thriller", + "Action Film", + "Crime Fiction" + ], + "name": "2 Fast 2 Furious", + "film_vector": [ + -0.3938395380973816, + -0.20215556025505066, + -0.1983330398797989, + 0.07062796503305435, + 0.0551629364490509, + -0.1585693657398224, + -0.046535804867744446, + -0.29045119881629944, + -0.11580471694469452, + -0.04617121070623398 + ] + }, + { + "id": "/en/7g_rainbow_colony", + "directed_by": [ + "Selvaraghavan" + ], + "initial_release_date": "2004-10-15", + "genre": [ + "Drama" + ], + "name": "7G Rainbow Colony", + "film_vector": [ + 0.16117042303085327, + 0.024516263976693153, + 0.002939242869615555, + -0.11122770607471466, + 0.034585122019052505, + 0.08294262737035751, + -0.14757220447063446, + 0.0377456434071064, + -0.0004929639399051666, + 0.02788071520626545 + ] + }, + { + "id": "/en/3-iron", + "directed_by": [ + "Kim Ki-duk" + ], + "initial_release_date": "2004-09-07", + "genre": [ + "Crime Fiction", + "Romance Film", + "East Asian cinema", + "World cinema", + "Drama" + ], + "name": "3-Iron", + "film_vector": [ + -0.5882613062858582, + 0.08123775571584702, + -0.0757257491350174, + -0.030296973884105682, + -0.019240837544202805, + -0.09596478193998337, + -0.04561401903629303, + -0.09680159389972687, + 0.03482966125011444, + -0.3140838146209717 + ] + }, + { + "id": "/en/10_5_apocalypse", + "directed_by": [ + "John Lafia" + ], + "initial_release_date": "2006-03-18", + "genre": [ + "Disaster Film", + "Thriller", + "Television film", + "Action/Adventure", + "Action Film" + ], + "name": "10.5: Apocalypse", + "film_vector": [ + -0.49060824513435364, + -0.18185612559318542, + -0.16036522388458252, + 0.1666317880153656, + -0.07451100647449493, + -0.21319782733917236, + -0.04665585979819298, + -0.06425370275974274, + -0.034817151725292206, + 0.0020883651450276375 + ] + }, + { + "id": "/en/8_mile", + "directed_by": [ + "Curtis Hanson" + ], + "initial_release_date": "2002-09-08", + "genre": [ + "Musical", + "Hip hop film", + "Drama", + "Musical Drama" + ], + "name": "8 Mile", + "film_vector": [ + -0.21515440940856934, + 0.059219345450401306, + -0.39070558547973633, + -0.057955846190452576, + -0.08906205743551254, + -0.2518461346626282, + -0.21613618731498718, + 0.025769298896193504, + 0.021249333396553993, + -0.021358411759138107 + ] + }, + { + "id": "/en/100_girls", + "directed_by": [ + "Michael Davis" + ], + "initial_release_date": "2001-09-25", + "genre": [ + "Romantic comedy", + "Romance Film", + "Indie film", + "Teen film", + "Comedy" + ], + "name": "100 Girls", + "film_vector": [ + -0.3523019552230835, + 0.020383162423968315, + -0.5542165040969849, + 0.19601628184318542, + 0.15341097116470337, + -0.15222683548927307, + -0.055879879742860794, + -0.10394058376550674, + 0.19957588613033295, + -0.02153446525335312 + ] + }, + { + "id": "/en/40_days_and_40_nights", + "directed_by": [ + "Michael Lehmann" + ], + "initial_release_date": "2002-03-01", + "genre": [ + "Romance Film", + "Romantic comedy", + "Sex comedy", + "Comedy", + "Drama" + ], + "name": "40 Days and 40 Nights", + "film_vector": [ + -0.20648512244224548, + 0.059475746005773544, + -0.4538213312625885, + 0.07723864912986755, + 0.20519894361495972, + -0.16071775555610657, + -0.06368835270404816, + 0.06953878700733185, + -0.017263829708099365, + -0.14547200500965118 + ] + }, + { + "id": "/en/50_cent_the_new_breed", + "directed_by": [ + "Don Robinson", + "Damon Johnson", + "Philip Atwell", + "Ian Inaba", + "Stephen Marshall", + "John Quigley", + "Jessy Terrero", + "Noa Shaw" + ], + "initial_release_date": "2003-04-15", + "genre": [ + "Documentary film", + "Music", + "Concert film", + "Biographical film" + ], + "name": "50 Cent: The New Breed", + "film_vector": [ + -0.13960939645767212, + -0.05368714779615402, + -0.1786518096923828, + -0.024731852114200592, + -0.037756361067295074, + -0.411176860332489, + -0.10299503803253174, + -0.07155707478523254, + 0.07050137221813202, + 0.08763235807418823 + ] + }, + { + "id": "/en/3_the_dale_earnhardt_story", + "directed_by": [ + "Russell Mulcahy" + ], + "initial_release_date": "2004-12-11", + "genre": [ + "Sports", + "Auto racing", + "Biographical film", + "Drama" + ], + "name": "3: The Dale Earnhardt Story", + "film_vector": [ + -0.03260286897420883, + -0.055107515305280685, + -0.060970183461904526, + -0.06157175451517105, + -0.129171684384346, + -0.2096874713897705, + -0.23608532547950745, + -0.1949222981929779, + -0.05367223545908928, + -0.008083447813987732 + ] + }, + { + "id": "/en/61__2001", + "directed_by": [ + "Billy Crystal" + ], + "initial_release_date": "2001-04-28", + "genre": [ + "Sports", + "History", + "Historical period drama", + "Television film", + "Drama" + ], + "name": "61*", + "film_vector": [ + -0.3335360288619995, + 0.22267481684684753, + -0.03506709635257721, + -0.244353249669075, + -0.2584801912307739, + -0.025642188265919685, + -0.14719580113887787, + 0.00678938627243042, + -0.034271448850631714, + -0.2309035360813141 + ] + }, + { + "id": "/en/24_hour_party_people", + "directed_by": [ + "Michael Winterbottom" + ], + "initial_release_date": "2002-02-13", + "genre": [ + "Biographical film", + "Comedy-drama", + "Comedy", + "Music", + "Drama" + ], + "name": "24 Hour Party People", + "film_vector": [ + 0.023176079615950584, + 0.07373621314764023, + -0.36906668543815613, + -0.10261218994855881, + -0.031135238707065582, + -0.22243686020374298, + 0.07193347811698914, + -0.03466861695051193, + 0.11265094578266144, + -0.12490998208522797 + ] + }, + { + "id": "/en/10th_wolf", + "directed_by": [ + "Robert Moresco" + ], + "initial_release_date": "2006-08-18", + "genre": [ + "Mystery", + "Thriller", + "Crime Fiction", + "Crime Thriller", + "Gangster Film", + "Drama" + ], + "name": "10th & Wolf", + "film_vector": [ + -0.5078380107879639, + -0.3439369797706604, + -0.2657935321331024, + -0.08391005545854568, + -0.10034256428480148, + -0.05617382377386093, + 0.022089768201112747, + -0.08627504110336304, + 0.0027772989124059677, + -0.19207152724266052 + ] + }, + { + "id": "/en/25th_hour", + "directed_by": [ + "Spike Lee" + ], + "initial_release_date": "2002-12-16", + "genre": [ + "Crime Fiction", + "Drama" + ], + "name": "25th Hour", + "film_vector": [ + -0.3642333149909973, + -0.21776464581489563, + -0.20917880535125732, + -0.25713181495666504, + -0.07456870377063751, + 0.04838301241397858, + 0.022817065939307213, + -0.18383491039276123, + 0.02906203642487526, + -0.30453991889953613 + ] + }, + { + "id": "/en/7_seconds_2005", + "directed_by": [ + "Simon Fellows" + ], + "initial_release_date": "2005-06-28", + "genre": [ + "Thriller", + "Action Film", + "Crime Fiction" + ], + "name": "7 Seconds", + "film_vector": [ + -0.4892546236515045, + -0.27424466609954834, + -0.17404383420944214, + -0.041237328201532364, + 0.013733255676925182, + -0.14865872263908386, + 0.0038244975730776787, + -0.20082694292068481, + 0.010233888402581215, + -0.10713657736778259 + ] + }, + { + "id": "/en/28_days_later", + "directed_by": [ + "Danny Boyle" + ], + "initial_release_date": "2002-11-01", + "genre": [ + "Science Fiction", + "Horror", + "Thriller" + ], + "name": "28 Days Later", + "film_vector": [ + -0.37326112389564514, + -0.35833847522735596, + -0.1640438288450241, + 0.029856616631150246, + 0.12030060589313507, + -0.09048760682344437, + -0.014864383265376091, + -0.0583636537194252, + 0.09206384420394897, + -0.07684420049190521 + ] + }, + { + "id": "/en/21_grams", + "directed_by": [ + "Alejandro Gonz\u00e1lez I\u00f1\u00e1rritu" + ], + "initial_release_date": "2003-09-05", + "genre": [ + "Thriller", + "Ensemble Film", + "Crime Fiction", + "Drama" + ], + "name": "21 Grams", + "film_vector": [ + -0.406351238489151, + -0.19689790904521942, + -0.3217048645019531, + -0.03450096398591995, + 0.03857141360640526, + -0.20135176181793213, + -0.0021787025034427643, + -0.19001689553260803, + 0.1703125238418579, + -0.04296879470348358 + ] + }, + { + "id": "/en/9th_company", + "directed_by": [ + "Fedor Bondarchuk" + ], + "initial_release_date": "2005-09-29", + "genre": [ + "War film", + "Action Film", + "Historical fiction", + "Drama" + ], + "name": "The 9th Company", + "film_vector": [ + -0.38192126154899597, + 0.07342447340488434, + 0.06082271784543991, + -0.013796567916870117, + 0.03550833463668823, + -0.22433343529701233, + -0.13065224885940552, + -0.027570728212594986, + -0.12619267404079437, + -0.2872225046157837 + ] + }, + { + "id": "/en/102_dalmatians", + "directed_by": [ + "Kevin Lima" + ], + "initial_release_date": "2000-11-22", + "genre": [ + "Family", + "Adventure Film", + "Comedy" + ], + "name": "102 Dalmatians", + "film_vector": [ + 0.042570389807224274, + 0.06343232840299606, + -0.24327720701694489, + 0.3970237374305725, + 0.11796928197145462, + -0.12179441004991531, + -0.04489295929670334, + -0.06388561427593231, + -0.061598703265190125, + -0.29069703817367554 + ] + }, + { + "id": "/en/16_years_of_alcohol", + "directed_by": [ + "Richard Jobson" + ], + "initial_release_date": "2003-08-14", + "genre": [ + "Indie film", + "Drama" + ], + "name": "16 Years of Alcohol", + "film_vector": [ + -0.14482469856739044, + -0.042774688452482224, + -0.21236354112625122, + -0.04204161465167999, + 0.12523362040519714, + -0.25398993492126465, + 0.009951010346412659, + -0.25440630316734314, + 0.2939412593841553, + -0.14595136046409607 + ] + }, + { + "id": "/en/12b", + "directed_by": [ + "Jeeva" + ], + "initial_release_date": "2001-09-28", + "genre": [ + "Romance Film", + "Comedy", + "Tamil cinema", + "World cinema", + "Drama" + ], + "name": "12B", + "film_vector": [ + -0.581878125667572, + 0.35237908363342285, + -0.1303335428237915, + 0.07984604686498642, + 0.063065305352211, + -0.069791778922081, + 0.0921832025051117, + -0.12192240357398987, + -0.03154759854078293, + -0.07104311138391495 + ] + }, + { + "id": "/en/2009_lost_memories", + "directed_by": [ + "Lee Si-myung" + ], + "initial_release_date": "2002-02-01", + "genre": [ + "Thriller", + "Action Film", + "Science Fiction", + "Mystery", + "Drama" + ], + "name": "2009 Lost Memories", + "film_vector": [ + -0.2455712854862213, + -0.2628556489944458, + -0.08022062480449677, + 0.03692961856722832, + 0.2620014548301697, + -0.15426300466060638, + -0.03795433044433594, + -0.07345929741859436, + 0.10071136057376862, + -0.06852547824382782 + ] + }, + { + "id": "/en/16_blocks", + "directed_by": [ + "Richard Donner" + ], + "initial_release_date": "2006-03-01", + "genre": [ + "Thriller", + "Crime Fiction", + "Action Film", + "Drama" + ], + "name": "16 Blocks", + "film_vector": [ + -0.5198523998260498, + -0.15682370960712433, + -0.23324376344680786, + -0.03169954568147659, + -0.11605948954820633, + -0.06740964204072952, + 0.007243060506880283, + -0.1694997251033783, + 0.11897595226764679, + -0.15224257111549377 + ] + }, + { + "id": "/en/15_minutes", + "directed_by": [ + "John Herzfeld" + ], + "initial_release_date": "2001-03-01", + "genre": [ + "Thriller", + "Action Film", + "Crime Fiction", + "Crime Thriller", + "Drama" + ], + "name": "15 Minutes", + "film_vector": [ + -0.5263476371765137, + -0.2854498326778412, + -0.24405723810195923, + -0.04939351975917816, + -0.030202312394976616, + -0.1324872374534607, + 0.0067596472799777985, + -0.1293065845966339, + -0.008704623207449913, + -0.07119792699813843 + ] + }, + { + "id": "/en/50_first_dates", + "directed_by": [ + "Peter Segal" + ], + "initial_release_date": "2004-02-13", + "genre": [ + "Romantic comedy", + "Romance Film", + "Comedy" + ], + "name": "50 First Dates", + "film_vector": [ + -0.2219598889350891, + 0.0604281947016716, + -0.5732376575469971, + 0.14279109239578247, + 0.19710275530815125, + -0.1629033386707306, + -0.04924710839986801, + -0.08619055151939392, + 0.050503626465797424, + -0.09984859079122543 + ] + }, + { + "id": "/en/9_songs", + "directed_by": [ + "Michael Winterbottom" + ], + "initial_release_date": "2004-05-16", + "genre": [ + "Erotica", + "Musical", + "Romance Film", + "Erotic Drama", + "Musical Drama", + "Drama" + ], + "name": "9 Songs", + "film_vector": [ + -0.3608056306838989, + 0.20093542337417603, + -0.33303651213645935, + -0.08330017328262329, + 0.12216074764728546, + -0.02024378627538681, + -0.04221656545996666, + 0.22092020511627197, + 0.20554018020629883, + -0.00449637696146965 + ] + }, + { + "id": "/en/20_fingers_2004", + "directed_by": [ + "Mania Akbari" + ], + "initial_release_date": "2004-09-01", + "genre": [ + "World cinema", + "Drama" + ], + "name": "20 Fingers", + "film_vector": [ + -0.31201350688934326, + 0.13122373819351196, + -0.0770883560180664, + -0.019758764654397964, + -0.008387040346860886, + -0.21523043513298035, + 0.01474076509475708, + -0.06844805181026459, + 0.2350933849811554, + -0.18507416546344757 + ] + }, + { + "id": "/en/3_needles", + "directed_by": [ + "Thom Fitzgerald" + ], + "initial_release_date": "2006-12-01", + "genre": [ + "Indie film", + "Social problem film", + "Chinese Movies", + "Drama" + ], + "name": "3 Needles", + "film_vector": [ + -0.3596230745315552, + 0.11733835935592651, + -0.20433488488197327, + -0.025732195004820824, + 0.07282141596078873, + -0.24452540278434753, + 0.027140304446220398, + -0.08328370004892349, + 0.2654515504837036, + -0.11258786916732788 + ] + }, + { + "id": "/en/28_days_2000", + "directed_by": [ + "Betty Thomas" + ], + "initial_release_date": "2000-02-08", + "genre": [ + "Comedy-drama", + "Romantic comedy", + "Comedy", + "Drama" + ], + "name": "28 Days", + "film_vector": [ + -0.2045252025127411, + 0.01913375034928322, + -0.5538102388381958, + 0.013650903478264809, + 0.023556701838970184, + -0.12081187218427658, + -0.04030195251107216, + -0.015531345270574093, + -0.047772184014320374, + -0.11525265872478485 + ] + }, + { + "id": "/en/36_china_town", + "directed_by": [ + "Abbas Burmawalla", + "Mustan Burmawalla" + ], + "initial_release_date": "2006-04-21", + "genre": [ + "Thriller", + "Musical", + "Comedy", + "Mystery", + "Crime Fiction", + "Bollywood", + "Musical comedy" + ], + "name": "36 China Town", + "film_vector": [ + -0.5037119388580322, + 0.1049385517835617, + -0.3130909502506256, + 0.029526378959417343, + -0.09424923360347748, + -0.05151926726102829, + 0.12222763895988464, + -0.11977501213550568, + 0.0638146623969078, + -0.16538026928901672 + ] + }, + { + "id": "/en/7_mujeres_1_homosexual_y_carlos", + "directed_by": [ + "Rene Bueno" + ], + "initial_release_date": "2004-06-01", + "genre": [ + "Romantic comedy", + "LGBT", + "Romance Film", + "World cinema", + "Sex comedy", + "Comedy", + "Drama" + ], + "name": "7 mujeres, 1 homosexual y Carlos", + "film_vector": [ + -0.28663069009780884, + 0.16166985034942627, + -0.37481510639190674, + 0.02511240728199482, + -0.010751367546617985, + -0.0866774171590805, + -0.0026325471699237823, + 0.0262901671230793, + 0.20098450779914856, + -0.1331687569618225 + ] + }, + { + "id": "/en/88_minutes", + "directed_by": [ + "Jon Avnet" + ], + "initial_release_date": "2007-02-14", + "genre": [ + "Thriller", + "Psychological thriller", + "Mystery", + "Drama" + ], + "name": "88 Minutes", + "film_vector": [ + -0.3991270065307617, + -0.29399359226226807, + -0.18067818880081177, + -0.039887502789497375, + 0.14684034883975983, + -0.11010734736919403, + 0.034898944199085236, + -0.014728846028447151, + 0.014881398528814316, + -0.08462448418140411 + ] + }, + { + "id": "/en/500_years_later", + "directed_by": [ + "Owen 'Alik Shahadah" + ], + "initial_release_date": "2005-10-11", + "genre": [ + "Indie film", + "Documentary film", + "History" + ], + "name": "500 Years Later", + "film_vector": [ + -0.2372656762599945, + 0.11090922355651855, + 0.04285892844200134, + -0.049169644713401794, + -0.15963061153888702, + -0.43325862288475037, + -0.1595364809036255, + -0.03303607553243637, + 0.25509166717529297, + -0.18386732041835785 + ] + }, + { + "id": "/en/50_ways_of_saying_fabulous", + "directed_by": [ + "Stewart Main" + ], + "genre": [ + "LGBT", + "Indie film", + "Historical period drama", + "Gay Themed", + "World cinema", + "Coming of age", + "Drama" + ], + "name": "50 Ways of Saying Fabulous", + "film_vector": [ + -0.27887481451034546, + 0.18994255363941193, + -0.33993980288505554, + 0.004722374025732279, + -0.21048058569431305, + -0.1383395791053772, + -0.13690531253814697, + 0.060546182096004486, + 0.2729519009590149, + -0.12975478172302246 + ] + }, + { + "id": "/en/5x2", + "directed_by": [ + "Fran\u00e7ois Ozon" + ], + "initial_release_date": "2004-09-01", + "genre": [ + "Romance Film", + "World cinema", + "Marriage Drama", + "Fiction", + "Drama" + ], + "name": "5x2", + "film_vector": [ + -0.5077643990516663, + 0.2671087980270386, + -0.2828234136104584, + -0.08828767389059067, + -0.038876283913850784, + -0.04873079061508179, + -0.05571460723876953, + -0.022713705897331238, + 0.09934085607528687, + -0.19531087577342987 + ] + }, + { + "id": "/en/28_weeks_later", + "directed_by": [ + "Juan Carlos Fresnadillo" + ], + "initial_release_date": "2007-04-26", + "genre": [ + "Science Fiction", + "Horror", + "Thriller" + ], + "name": "28 Weeks Later", + "film_vector": [ + -0.38142067193984985, + -0.3868202567100525, + -0.13064610958099365, + -0.0032912609167397022, + 0.10928447544574738, + -0.05982154235243797, + 0.02063712105154991, + -0.04957783222198486, + 0.1435815691947937, + -0.05924663692712784 + ] + }, + { + "id": "/en/10_5", + "directed_by": [ + "John Lafia" + ], + "initial_release_date": "2004-05-02", + "genre": [ + "Disaster Film", + "Thriller", + "Action/Adventure", + "Drama" + ], + "name": "10.5", + "film_vector": [ + -0.4205099642276764, + -0.23010940849781036, + -0.19305548071861267, + 0.11639359593391418, + 0.12660717964172363, + -0.14069679379463196, + -0.03923504054546356, + -0.0756281316280365, + -0.01408003643155098, + -0.029093340039253235 + ] + }, + { + "id": "/en/13_going_on_30", + "directed_by": [ + "Gary Winick" + ], + "initial_release_date": "2004-04-14", + "genre": [ + "Romantic comedy", + "Coming of age", + "Fantasy", + "Romance Film", + "Fantasy Comedy", + "Comedy" + ], + "name": "13 Going on 30", + "film_vector": [ + -0.32570263743400574, + 0.06900060921907425, + -0.5648012161254883, + 0.2037995457649231, + -0.1037881076335907, + 0.05938105657696724, + -0.08619556576013565, + -0.05850786343216896, + 0.18934500217437744, + -0.09267889708280563 + ] + }, + { + "id": "/en/2ldk", + "directed_by": [ + "Yukihiko Tsutsumi" + ], + "initial_release_date": "2004-05-13", + "genre": [ + "LGBT", + "Thriller", + "Psychological thriller", + "World cinema", + "Japanese Movies", + "Comedy", + "Drama" + ], + "name": "2LDK", + "film_vector": [ + -0.572184145450592, + 0.007371002808213234, + -0.24004386365413666, + 0.09006163477897644, + -0.12229356169700623, + -0.030307725071907043, + 0.05826348066329956, + -0.12868906557559967, + 0.24812546372413635, + -0.10051698982715607 + ] + }, + { + "id": "/en/7_phere", + "directed_by": [ + "Ishaan Trivedi" + ], + "initial_release_date": "2005-07-29", + "genre": [ + "Bollywood", + "Comedy", + "Drama" + ], + "name": "7\u00bd Phere", + "film_vector": [ + -0.4259541928768158, + 0.3583088219165802, + -0.18741139769554138, + -0.007408754900097847, + -0.025874558836221695, + 0.03644401580095291, + 0.1692209541797638, + -0.16710403561592102, + -0.010077720507979393, + -0.05494922399520874 + ] + }, + { + "id": "/en/a_beautiful_mind", + "directed_by": [ + "Ron Howard" + ], + "initial_release_date": "2001-12-13", + "genre": [ + "Biographical film", + "Psychological thriller", + "Historical period drama", + "Romance Film", + "Marriage Drama", + "Documentary film", + "Drama" + ], + "name": "A Beautiful Mind", + "film_vector": [ + -0.54057377576828, + 0.01405918225646019, + -0.28716331720352173, + -0.029463564977049828, + 0.021345268934965134, + -0.27627086639404297, + -0.12171049416065216, + 0.0636940747499466, + 0.06281324476003647, + -0.15485233068466187 + ] + }, + { + "id": "/en/a_cinderella_story", + "directed_by": [ + "Mark Rosman" + ], + "initial_release_date": "2004-07-10", + "genre": [ + "Teen film", + "Romantic comedy", + "Romance Film", + "Family", + "Comedy" + ], + "name": "A Cinderella Story", + "film_vector": [ + -0.2911830544471741, + 0.04913898557424545, + -0.5120959877967834, + 0.22987619042396545, + 0.15435227751731873, + -0.049760278314352036, + -0.19199621677398682, + 0.07798704504966736, + 0.05665161460638046, + -0.1736373007297516 + ] + }, + { + "id": "/en/a_cock_and_bull_story", + "directed_by": [ + "Michael Winterbottom" + ], + "initial_release_date": "2005-07-17", + "genre": [ + "Mockumentary", + "Indie film", + "Comedy", + "Drama" + ], + "name": "A Cock and Bull Story", + "film_vector": [ + 0.052551496773958206, + -0.026447534561157227, + -0.29425525665283203, + 0.10573646426200867, + 0.09005451202392578, + -0.34870845079421997, + 0.0632634237408638, + -0.10015638917684555, + 0.025399385020136833, + -0.09683854877948761 + ] + }, + { + "id": "/en/a_common_thread", + "directed_by": [ + "\u00c9l\u00e9onore Faucher" + ], + "initial_release_date": "2004-05-14", + "genre": [ + "Romance Film", + "Drama" + ], + "name": "A Common Thread", + "film_vector": [ + -0.16133970022201538, + 0.13339219987392426, + -0.3282521069049835, + 0.04129435122013092, + 0.39513909816741943, + -0.01959371007978916, + -0.08963336050510406, + -0.04987513646483421, + 0.09146498888731003, + -0.15931521356105804 + ] + }, + { + "id": "/en/a_dirty_shame", + "directed_by": [ + "John Waters" + ], + "initial_release_date": "2004-09-12", + "genre": [ + "Sex comedy", + "Cult film", + "Parody", + "Black comedy", + "Gross out", + "Gross-out film", + "Comedy" + ], + "name": "A Dirty Shame", + "film_vector": [ + -0.16974136233329773, + -0.10099861770868301, + -0.4178960919380188, + 0.026075437664985657, + 0.002779947593808174, + -0.3274763822555542, + 0.21005737781524658, + 0.24578827619552612, + -0.07150798290967941, + -0.08124201744794846 + ] + }, + { + "id": "/en/a_duo_occasion", + "directed_by": [ + "Pierre Lamoureux" + ], + "initial_release_date": "2005-11-22", + "genre": [ + "Music video" + ], + "name": "A Duo Occasion", + "film_vector": [ + 0.1315498799085617, + 0.08221473544836044, + -0.13062727451324463, + 0.03152387961745262, + 0.23046541213989258, + -0.17213162779808044, + -0.01958809420466423, + -0.0010683555155992508, + 0.19306319952011108, + 0.18292203545570374 + ] + }, + { + "id": "/en/a_good_year", + "directed_by": [ + "Ridley Scott" + ], + "initial_release_date": "2006-09-09", + "genre": [ + "Romantic comedy", + "Film adaptation", + "Romance Film", + "Comedy-drama", + "Slice of life", + "Comedy of manners", + "Comedy", + "Drama" + ], + "name": "A Good Year", + "film_vector": [ + -0.31561434268951416, + 0.05888581648468971, + -0.5888196229934692, + 0.07696505635976791, + -0.0048791468143463135, + -0.16373160481452942, + -0.06272971630096436, + 0.1478448510169983, + -0.08336278796195984, + -0.08936698734760284 + ] + }, + { + "id": "/en/a_history_of_violence_2005", + "directed_by": [ + "David Cronenberg" + ], + "initial_release_date": "2005-05-16", + "genre": [ + "Thriller", + "Psychological thriller", + "Crime Fiction", + "Drama" + ], + "name": "A History of Violence", + "film_vector": [ + -0.5082744359970093, + -0.2712077498435974, + -0.10918865352869034, + -0.2634924650192261, + -0.10997879505157471, + -0.07414699345827103, + 0.009091394022107124, + 0.0822678804397583, + 0.0005032997578382492, + -0.18103225529193878 + ] + }, + { + "id": "/en/ett_hal_i_mitt_hjarta", + "directed_by": [ + "Lukas Moodysson" + ], + "initial_release_date": "2004-09-10", + "genre": [ + "Horror", + "Experimental film", + "Social problem film", + "Drama" + ], + "name": "A Hole in My Heart", + "film_vector": [ + -0.34756404161453247, + -0.055599868297576904, + -0.13784259557724, + -0.024800563231110573, + -0.006157858297228813, + -0.24098899960517883, + 0.0648055449128151, + 0.007202983368188143, + 0.3687819540500641, + -0.12279640883207321 + ] + }, + { + "id": "/en/a_knights_tale", + "directed_by": [ + "Brian Helgeland" + ], + "initial_release_date": "2001-03-08", + "genre": [ + "Romantic comedy", + "Adventure Film", + "Action Film", + "Action/Adventure", + "Historical period drama", + "Costume Adventure", + "Comedy", + "Drama" + ], + "name": "A Knight's Tale", + "film_vector": [ + -0.37733137607574463, + 0.004295038059353828, + -0.35530537366867065, + 0.2155059576034546, + -0.07662102580070496, + -0.09958954155445099, + -0.22082987427711487, + 0.20595018565654755, + -0.14820712804794312, + -0.261717289686203 + ] + }, + { + "id": "/en/a_league_of_ordinary_gentlemen", + "directed_by": [ + "Christopher Browne", + "Alexander H. Browne" + ], + "initial_release_date": "2006-03-21", + "genre": [ + "Documentary film", + "Sports", + "Culture & Society", + "Biographical film" + ], + "name": "A League of Ordinary Gentlemen", + "film_vector": [ + -0.11056849360466003, + 0.016764160245656967, + -0.15258803963661194, + -0.09296280145645142, + -0.06126102805137634, + -0.39742183685302734, + -0.23234093189239502, + -0.15288865566253662, + 0.07876819372177124, + -0.1825604885816574 + ] + }, + { + "id": "/en/a_little_trip_to_heaven", + "directed_by": [ + "Baltasar Korm\u00e1kur" + ], + "initial_release_date": "2005-12-26", + "genre": [ + "Thriller", + "Crime Fiction", + "Black comedy", + "Indie film", + "Comedy-drama", + "Detective fiction", + "Ensemble Film", + "Drama" + ], + "name": "A Little Trip to Heaven", + "film_vector": [ + -0.32260215282440186, + -0.17480753362178802, + -0.45595183968544006, + 0.0010018348693847656, + 0.09713864326477051, + -0.17081782221794128, + -0.057883165776729584, + 0.042861491441726685, + 0.05419326573610306, + -0.15091097354888916 + ] + }, + { + "id": "/en/a_lot_like_love", + "directed_by": [ + "Nigel Cole" + ], + "initial_release_date": "2005-04-21", + "genre": [ + "Romantic comedy", + "Romance Film", + "Comedy-drama", + "Comedy", + "Drama" + ], + "name": "A Lot like Love", + "film_vector": [ + -0.43509402871131897, + 0.18234071135520935, + -0.5632947683334351, + 0.02624398097395897, + 0.02744414284825325, + -0.003058863803744316, + -0.029186271131038666, + 0.07741448283195496, + 0.05817003920674324, + -0.10241740196943283 + ] + }, + { + "id": "/en/a_love_song_for_bobby_long", + "directed_by": [ + "Shainee Gabel" + ], + "initial_release_date": "2004-09-02", + "genre": [ + "Film adaptation", + "Melodrama", + "Drama" + ], + "name": "A Love Song for Bobby Long", + "film_vector": [ + -0.005023850128054619, + 0.1497935652732849, + -0.26658380031585693, + -0.046829067170619965, + 0.3261561393737793, + -0.21126766502857208, + -0.11854884028434753, + -0.021191604435443878, + 0.04819224402308464, + -0.20855014026165009 + ] + }, + { + "id": "/en/a_man_a_real_one", + "directed_by": [ + "Arnaud Larrieu", + "Jean-Marie Larrieu" + ], + "initial_release_date": "2003-05-28", + "genre": [ + "Comedy", + "Drama" + ], + "name": "A Man, a Real One", + "film_vector": [ + -0.15855395793914795, + 0.11348956823348999, + -0.35988950729370117, + -0.08266322314739227, + -0.11525187641382217, + -0.030198868364095688, + 0.07689502835273743, + -0.04268482327461243, + 0.002597969491034746, + -0.21267428994178772 + ] + }, + { + "id": "/en/a_midsummer_nights_rave", + "directed_by": [ + "Gil Cates Jr." + ], + "genre": [ + "Romance Film", + "Romantic comedy", + "Teen film", + "Comedy", + "Drama" + ], + "name": "A Midsummer Night's Rave", + "film_vector": [ + -0.21555089950561523, + 0.039304401725530624, + -0.5214757323265076, + 0.04338296502828598, + 0.16380102932453156, + -0.025877580046653748, + -0.12386463582515717, + 0.23418904840946198, + 0.08780020475387573, + -0.10225269198417664 + ] + }, + { + "id": "/en/a_mighty_wind", + "directed_by": [ + "Christopher Guest" + ], + "initial_release_date": "2003-03-12", + "genre": [ + "Mockumentary", + "Parody", + "Musical", + "Musical comedy", + "Comedy" + ], + "name": "A Mighty Wind", + "film_vector": [ + 0.1317680925130844, + 0.12688393890857697, + -0.312492311000824, + 0.07617104053497314, + -0.15337958931922913, + -0.16659235954284668, + 0.02258704975247383, + 0.2457401156425476, + -0.17055854201316833, + -0.14747780561447144 + ] + }, + { + "id": "/en/a_perfect_day", + "directed_by": [ + "Khalil Joreige", + "Joana Hadjithomas" + ], + "genre": [ + "World cinema", + "Drama" + ], + "name": "A Perfect Day", + "film_vector": [ + -0.20155593752861023, + 0.15355059504508972, + -0.04786144196987152, + -0.05642329901456833, + 0.160729318857193, + -0.16448506712913513, + -0.061925582587718964, + -0.0641707256436348, + 0.14850927889347076, + -0.14488781988620758 + ] + }, + { + "id": "/en/a_prairie_home_companion_2006", + "directed_by": [ + "Robert Altman" + ], + "initial_release_date": "2006-02-12", + "genre": [ + "Musical comedy", + "Drama" + ], + "name": "A Prairie Home Companion", + "film_vector": [ + 0.13310453295707703, + 0.10885767638683319, + -0.39043280482292175, + 0.09072832763195038, + -0.02959716133773327, + -0.01530890166759491, + -0.07123421132564545, + -0.019741158932447433, + 0.01010694820433855, + -0.3303288221359253 + ] + }, + { + "id": "/en/a_ring_of_endless_light_2002", + "directed_by": [ + "Greg Beeman" + ], + "initial_release_date": "2002-08-23", + "genre": [ + "Drama" + ], + "name": "A Ring of Endless Light", + "film_vector": [ + 0.02411145716905594, + 0.024355106055736542, + 0.03555737063288689, + -0.07200195640325546, + -0.0001396872103214264, + 0.10361523181200027, + -0.07974714040756226, + 0.14948159456253052, + 0.0003902330936398357, + -0.04392610862851143 + ] + }, + { + "id": "/en/a_scanner_darkly_2006", + "directed_by": [ + "Richard Linklater" + ], + "initial_release_date": "2006-07-07", + "genre": [ + "Science Fiction", + "Dystopia", + "Animation", + "Future noir", + "Film adaptation", + "Thriller", + "Drama" + ], + "name": "A Scanner Darkly", + "film_vector": [ + -0.5253639221191406, + -0.24242781102657318, + -0.1631498485803604, + 0.018939515575766563, + -0.1698339879512787, + -0.09111961722373962, + 0.017409196123480797, + -0.018322713673114777, + 0.14410993456840515, + -0.14514803886413574 + ] + }, + { + "id": "/en/a_short_film_about_john_bolton", + "directed_by": [ + "Neil Gaiman" + ], + "genre": [ + "Documentary film", + "Short Film", + "Black comedy", + "Indie film", + "Mockumentary", + "Graphic & Applied Arts", + "Comedy", + "Biographical film" + ], + "name": "A Short Film About John Bolton", + "film_vector": [ + -0.1045270785689354, + -0.018962835893034935, + -0.2669418156147003, + -0.038989778608083725, + -0.044324636459350586, + -0.4751920700073242, + 0.003770211711525917, + 0.04660744220018387, + 0.08276063948869705, + 0.013946013525128365 + ] + }, + { + "id": "/en/a_shot_in_the_west", + "directed_by": [ + "Bob Kelly" + ], + "initial_release_date": "2006-07-16", + "genre": [ + "Western", + "Short Film" + ], + "name": "A Shot in the West", + "film_vector": [ + 0.09604855626821518, + -0.03847790136933327, + -0.0030350396409630775, + 0.008531654253602028, + 0.13913699984550476, + -0.3467567265033722, + -0.09813524782657623, + -0.10677048563957214, + -0.03680156543850899, + -0.19511860609054565 + ] + }, + { + "id": "/en/a_sound_of_thunder_2005", + "directed_by": [ + "Peter Hyams" + ], + "initial_release_date": "2005-05-15", + "genre": [ + "Science Fiction", + "Adventure Film", + "Thriller", + "Action Film", + "Apocalyptic and post-apocalyptic fiction", + "Time travel" + ], + "name": "A Sound of Thunder", + "film_vector": [ + -0.45895102620124817, + -0.21119537949562073, + -0.05761144310235977, + 0.13901276886463165, + -0.15606553852558136, + -0.15532904863357544, + -0.1565360724925995, + 0.0022126687690615654, + -0.017141712829470634, + -0.08291098475456238 + ] + }, + { + "id": "/en/a_state_of_mind", + "directed_by": [ + "Daniel Gordon" + ], + "initial_release_date": "2005-08-10", + "genre": [ + "Documentary film", + "Political cinema", + "Sports" + ], + "name": "A State of Mind", + "film_vector": [ + -0.23483842611312866, + 0.17725372314453125, + 0.049057990312576294, + -0.11926323175430298, + -0.17619849741458893, + -0.3128635883331299, + -0.098695769906044, + -0.1284874826669693, + 0.20661720633506775, + -0.0028502303175628185 + ] + }, + { + "id": "/en/a_time_for_drunken_horses", + "directed_by": [ + "Bahman Ghobadi" + ], + "genre": [ + "World cinema", + "War film", + "Drama" + ], + "name": "A Time for Drunken Horses", + "film_vector": [ + -0.18754754960536957, + 0.1095699742436409, + -0.001102597452700138, + -0.0010783448815345764, + -0.04769830033183098, + -0.2687893509864807, + -0.07227511703968048, + 0.07325799763202667, + -0.01538950577378273, + -0.33092200756073 + ] + }, + { + "id": "/en/a_ton_image", + "directed_by": [ + "Aruna Villiers" + ], + "initial_release_date": "2004-05-26", + "genre": [ + "Thriller", + "Science Fiction" + ], + "name": "\u00c0 ton image", + "film_vector": [ + -0.3995548486709595, + -0.3675992488861084, + -0.008289404213428497, + 0.02598695084452629, + 0.11677856743335724, + -0.02324097603559494, + 0.06820331513881683, + -0.11463922262191772, + 0.08208126574754715, + -0.09686557203531265 + ] + }, + { + "id": "/en/a_very_long_engagement", + "directed_by": [ + "Jean-Pierre Jeunet" + ], + "initial_release_date": "2004-10-27", + "genre": [ + "War film", + "Romance Film", + "World cinema", + "Drama" + ], + "name": "A Very Long Engagement", + "film_vector": [ + -0.43168532848358154, + 0.24670764803886414, + -0.19394075870513916, + 0.024315834045410156, + 0.21051155030727386, + -0.187096506357193, + -0.11778928339481354, + -0.019497156143188477, + 0.007861103862524033, + -0.20663365721702576 + ] + }, + { + "id": "/en/a_view_from_the_eiffel_tower", + "directed_by": [ + "Nikola Vuk\u010devi\u0107" + ], + "genre": [ + "Drama" + ], + "name": "A View from Eiffel Tower", + "film_vector": [ + 0.025037448853254318, + 0.07511898875236511, + 0.0041957031935453415, + -0.1783379316329956, + 0.04726775363087654, + -0.05783994123339653, + -0.11791251599788666, + 0.1957460343837738, + 0.02828984335064888, + -0.12366905808448792 + ] + }, + { + "id": "/en/a_walk_to_remember", + "directed_by": [ + "Adam Shankman" + ], + "initial_release_date": "2002-01-23", + "genre": [ + "Coming of age", + "Romance Film", + "Drama" + ], + "name": "A Walk to Remember", + "film_vector": [ + -0.26396822929382324, + -0.004778295289725065, + -0.40700680017471313, + 0.13161706924438477, + 0.210921511054039, + -0.12050116062164307, + -0.18712079524993896, + -0.09998735040426254, + 0.21575620770454407, + -0.14935342967510223 + ] + }, + { + "id": "/en/a_i", + "directed_by": [ + "Steven Spielberg" + ], + "initial_release_date": "2001-06-26", + "genre": [ + "Science Fiction", + "Future noir", + "Adventure Film", + "Drama" + ], + "name": "A.I. Artificial Intelligence", + "film_vector": [ + -0.4404400885105133, + -0.15073353052139282, + -0.10595326870679855, + 0.11625121533870697, + 0.01682109199464321, + -0.12938007712364197, + -0.10952290892601013, + -0.15644100308418274, + 0.05836649239063263, + -0.22023478150367737 + ] + }, + { + "id": "/en/a_k_a_tommy_chong", + "directed_by": [ + "Josh Gilbert" + ], + "initial_release_date": "2006-06-14", + "genre": [ + "Documentary film", + "Culture & Society", + "Law & Crime", + "Biographical film" + ], + "name": "a/k/a Tommy Chong", + "film_vector": [ + -0.04349418729543686, + 0.02814348042011261, + -0.1747075319290161, + -0.06928741186857224, + -0.05883428454399109, + -0.47527310252189636, + -0.039194442331790924, + -0.12590272724628448, + 0.02610655315220356, + -0.174507737159729 + ] + }, + { + "id": "/en/aalvar", + "directed_by": [ + "Chella" + ], + "initial_release_date": "2007-01-12", + "genre": [ + "Action Film", + "Tamil cinema", + "World cinema" + ], + "name": "Aalvar", + "film_vector": [ + -0.533711850643158, + 0.37813401222229004, + 0.14012081921100616, + 0.09574098885059357, + 0.06777354329824448, + -0.16138839721679688, + 0.07231991738080978, + -0.14673054218292236, + -0.02575819194316864, + -0.08276907354593277 + ] + }, + { + "id": "/en/aap_ki_khatir", + "directed_by": [ + "Dharmesh Darshan" + ], + "initial_release_date": "2006-08-25", + "genre": [ + "Romance Film", + "Romantic comedy", + "Bollywood", + "Drama" + ], + "name": "Aap Ki Khatir", + "film_vector": [ + -0.5035719871520996, + 0.33761268854141235, + -0.2684478163719177, + 0.11164705455303192, + 0.1861286163330078, + -0.011677632108330727, + 0.11038059741258621, + -0.11778943240642548, + -0.016941064968705177, + 0.05001305788755417 + ] + }, + { + "id": "/en/aaru_2005", + "directed_by": [ + "Hari" + ], + "initial_release_date": "2005-12-09", + "genre": [ + "Thriller", + "Action Film", + "Drama", + "Tamil cinema", + "World cinema" + ], + "name": "Aaru", + "film_vector": [ + -0.712161660194397, + 0.2528456449508667, + -0.007796340622007847, + 0.04293522611260414, + 0.0037270961329340935, + -0.11537735909223557, + 0.1275096833705902, + -0.09772567451000214, + 0.0022525377571582794, + -0.018881753087043762 + ] + }, + { + "id": "/en/aata", + "directed_by": [ + "V.N. Aditya" + ], + "initial_release_date": "2007-05-09", + "genre": [ + "Romance Film", + "Tollywood", + "World cinema" + ], + "name": "Aata", + "film_vector": [ + -0.5715155601501465, + 0.3951674699783325, + -0.12447037547826767, + 0.07182057946920395, + 0.23846185207366943, + -0.057157956063747406, + 0.08240543305873871, + -0.17360033094882965, + 0.0743287205696106, + -0.09186424314975739 + ] + }, + { + "id": "/en/aathi", + "directed_by": [ + "Ramana" + ], + "initial_release_date": "2006-01-14", + "genre": [ + "Thriller", + "Romance Film", + "Musical", + "Action Film", + "Tamil cinema", + "World cinema", + "Drama", + "Musical Drama" + ], + "name": "Aadhi", + "film_vector": [ + -0.7017087936401367, + 0.27162545919418335, + -0.18371880054473877, + 0.029996270313858986, + 0.038940925151109695, + -0.1335711032152176, + 0.05473273992538452, + 0.013838130049407482, + -0.014211906120181084, + 0.05626462772488594 + ] + }, + { + "id": "/en/aayitha_ezhuthu", + "directed_by": [ + "Mani Ratnam" + ], + "initial_release_date": "2004-05-21", + "genre": [ + "Thriller", + "Political thriller", + "Tamil cinema", + "World cinema", + "Drama" + ], + "name": "Aaytha Ezhuthu", + "film_vector": [ + -0.6471483707427979, + 0.22059650719165802, + -0.02000078186392784, + -0.01042139157652855, + 0.057838037610054016, + -0.11980952322483063, + 0.0936620831489563, + -0.04932260885834694, + 0.06948640197515488, + -0.07977205514907837 + ] + }, + { + "id": "/en/abandon_2002", + "directed_by": [ + "Stephen Gaghan" + ], + "initial_release_date": "2002-10-18", + "genre": [ + "Mystery", + "Thriller", + "Psychological thriller", + "Suspense", + "Drama" + ], + "name": "Abandon", + "film_vector": [ + -0.5696085691452026, + -0.33471280336380005, + -0.3051343262195587, + -0.09939010441303253, + -0.03613248094916344, + 0.009641693904995918, + 0.018205132335424423, + 0.09949488937854767, + 0.020121600478887558, + -0.041370589286088943 + ] + }, + { + "id": "/en/abduction_the_megumi_yokota_story", + "directed_by": [ + "Patty Kim", + "Chris Sheridan" + ], + "genre": [ + "Documentary film", + "Political cinema", + "Culture & Society", + "Law & Crime" + ], + "name": "Abduction: The Megumi Yokota Story", + "film_vector": [ + -0.1798814982175827, + -0.038461774587631226, + 0.10655070841312408, + -0.1585548222064972, + 0.0861097127199173, + -0.18145911395549774, + -0.05089838057756424, + -0.031828753650188446, + 0.24375265836715698, + -0.16060319542884827 + ] + }, + { + "id": "/en/about_a_boy_2002", + "directed_by": [ + "Chris Weitz", + "Paul Weitz" + ], + "initial_release_date": "2002-04-26", + "genre": [ + "Romance Film", + "Comedy", + "Drama" + ], + "name": "About a Boy", + "film_vector": [ + -0.2556988000869751, + 0.14022766053676605, + -0.3769262433052063, + 0.214120015501976, + 0.3526180386543274, + -0.03389493748545647, + -0.06014922633767128, + -0.15742459893226624, + 0.10592876374721527, + -0.09944458305835724 + ] + }, + { + "id": "/en/about_schmidt", + "directed_by": [ + "Alexander Payne" + ], + "initial_release_date": "2002-05-22", + "genre": [ + "Black comedy", + "Indie film", + "Comedy-drama", + "Tragicomedy", + "Comedy of manners", + "Comedy", + "Drama" + ], + "name": "About Schmidt", + "film_vector": [ + -0.18327312171459198, + 0.010314147919416428, + -0.46840330958366394, + -0.0948621928691864, + -0.1264810860157013, + -0.24606290459632874, + 0.0939776748418808, + 0.04576320946216583, + -0.009364464320242405, + -0.2034057378768921 + ] + }, + { + "id": "/en/accepted", + "directed_by": [ + "Steve Pink" + ], + "initial_release_date": "2006-08-18", + "genre": [ + "Teen film", + "Comedy" + ], + "name": "Accepted", + "film_vector": [ + -0.13174626231193542, + -0.0578923337161541, + -0.374251127243042, + 0.21597130596637726, + 0.2013501524925232, + -0.2039431631565094, + 0.06458347290754318, + -0.24971601366996765, + 0.23484289646148682, + -0.06511010229587555 + ] + }, + { + "id": "/en/across_the_hall", + "directed_by": [ + "Alex Merkin", + "Alex Merkin" + ], + "genre": [ + "Short Film", + "Thriller", + "Drama" + ], + "name": "Across the Hall", + "film_vector": [ + -0.14651423692703247, + -0.14606261253356934, + -0.17236484587192535, + -0.10633426904678345, + 0.2014656811952591, + -0.2461259365081787, + 0.05246315523982048, + -0.0579998642206192, + 0.18001945316791534, + -0.11763335764408112 + ] + }, + { + "id": "/en/adam_steve", + "directed_by": [ + "Craig Chester" + ], + "initial_release_date": "2005-04-24", + "genre": [ + "Romance Film", + "Romantic comedy", + "LGBT", + "Gay Themed", + "Indie film", + "Gay", + "Gay Interest", + "Comedy" + ], + "name": "Adam & Steve", + "film_vector": [ + -0.1771615445613861, + 0.07212629914283752, + -0.5713204145431519, + 0.13680993020534515, + 0.020186476409435272, + -0.16125516593456268, + -0.1242644190788269, + 0.04621630907058716, + 0.04995795339345932, + -0.04476252943277359 + ] + }, + { + "id": "/en/adam_resurrected", + "directed_by": [ + "Paul Schrader" + ], + "initial_release_date": "2008-08-30", + "genre": [ + "Historical period drama", + "Film adaptation", + "War film", + "Drama" + ], + "name": "Adam Resurrected", + "film_vector": [ + -0.20061376690864563, + 0.06451140344142914, + 0.060106467455625534, + -0.01585359498858452, + -0.03265521675348282, + -0.17779526114463806, + -0.1871803104877472, + 0.12872524559497833, + -0.011653796769678593, + -0.2457488775253296 + ] + }, + { + "id": "/en/adaptation_2002", + "directed_by": [ + "Spike Jonze" + ], + "initial_release_date": "2002-12-06", + "genre": [ + "Crime Fiction", + "Comedy", + "Drama" + ], + "name": "Adaptation", + "film_vector": [ + -0.4207225739955902, + -0.0499650277197361, + -0.18869119882583618, + -0.12213316559791565, + -0.19686871767044067, + -0.03485075756907463, + 0.07266031205654144, + -0.05321568250656128, + 0.03359717130661011, + -0.3343067467212677 + ] + }, + { + "id": "/en/address_unknown", + "directed_by": [ + "Kim Ki-duk" + ], + "initial_release_date": "2001-06-02", + "genre": [ + "War film", + "Drama" + ], + "name": "Address Unknown", + "film_vector": [ + -0.14728900790214539, + 0.036860980093479156, + 0.017893413081765175, + -0.0226543340831995, + 0.1914254128932953, + -0.37559762597084045, + -0.17596587538719177, + 0.015546261332929134, + -0.1420622617006302, + -0.3417631983757019 + ] + }, + { + "id": "/en/adrenaline_rush_2002", + "directed_by": [ + "Marc Fafard" + ], + "initial_release_date": "2002-10-18", + "genre": [ + "Documentary film", + "Short Film" + ], + "name": "Adrenaline Rush", + "film_vector": [ + -0.0672110766172409, + -0.12105122953653336, + 0.08059795200824738, + -0.036532968282699585, + 0.071243055164814, + -0.3907985985279083, + -0.08700445294380188, + -0.08941203355789185, + 0.20254887640476227, + 0.060542311519384384 + ] + }, + { + "id": "/en/essential_keys_to_better_bowling_2006", + "directed_by": [], + "genre": [ + "Documentary film", + "Sports" + ], + "name": "Essential Keys To Better Bowling", + "film_vector": [ + -0.02553773857653141, + 0.10525484383106232, + 0.09601041674613953, + -0.04163184016942978, + -0.14296738803386688, + -0.3117640018463135, + -0.06223466992378235, + -0.20882275700569153, + 0.10764876753091812, + 0.07635875046253204 + ] + }, + { + "id": "/en/adventures_into_digital_comics", + "directed_by": [ + "S\u00e9bastien Dumesnil" + ], + "genre": [ + "Documentary film" + ], + "name": "Adventures Into Digital Comics", + "film_vector": [ + 0.011506449431180954, + 0.023598676547408104, + 0.10552863776683807, + 0.14051459729671478, + -0.22956061363220215, + -0.1900804340839386, + -0.005392055958509445, + -0.13871519267559052, + 0.1799565851688385, + -0.07402472198009491 + ] + }, + { + "id": "/en/ae_fond_kiss", + "directed_by": [ + "Ken Loach" + ], + "initial_release_date": "2004-02-13", + "genre": [ + "Romance Film", + "Drama" + ], + "name": "Ae Fond Kiss...", + "film_vector": [ + -0.2611064016819, + 0.17780502140522003, + -0.28148263692855835, + 0.16298848390579224, + 0.4154796004295349, + -0.08041632920503616, + -0.038201283663511276, + -0.06889753043651581, + 0.09893926978111267, + -0.14346960186958313 + ] + }, + { + "id": "/en/aetbaar", + "directed_by": [ + "Vikram Bhatt" + ], + "initial_release_date": "2004-01-23", + "genre": [ + "Thriller", + "Romance Film", + "Mystery", + "Horror", + "Musical", + "Bollywood", + "World cinema", + "Drama", + "Musical Drama" + ], + "name": "Aetbaar", + "film_vector": [ + -0.6980562210083008, + 0.13949711620807648, + -0.24066439270973206, + 0.02026817761361599, + -0.03932848945260048, + -0.052967462688684464, + 0.03857365623116493, + 0.04439356178045273, + 0.06059592217206955, + -0.00815427117049694 + ] + }, + { + "id": "/en/aethiree", + "initial_release_date": "2004-04-23", + "genre": [ + "Comedy", + "Tamil cinema", + "World cinema" + ], + "directed_by": [ + "K. S. Ravikumar" + ], + "name": "Aethirree", + "film_vector": [ + -0.5127855539321899, + 0.40904539823532104, + -0.06948107481002808, + 0.051441531628370285, + -0.09032823145389557, + -0.18656545877456665, + 0.22284650802612305, + -0.07186967879533768, + 0.025574173778295517, + -0.14475250244140625 + ] + }, + { + "id": "/en/after_innocence", + "genre": [ + "Documentary film", + "Crime Fiction", + "Political cinema", + "Culture & Society", + "Law & Crime", + "Biographical film" + ], + "directed_by": [ + "Jessica Sanders" + ], + "name": "After Innocence", + "film_vector": [ + -0.44287213683128357, + -0.13707312941551208, + -0.14710362255573273, + -0.1750902533531189, + -0.09206987172365189, + -0.3351529836654663, + -0.08597804605960846, + -0.10616271197795868, + 0.18579858541488647, + -0.21576768159866333 + ] + }, + { + "id": "/en/after_the_sunset", + "initial_release_date": "2004-11-10", + "genre": [ + "Crime Fiction", + "Action/Adventure", + "Action Film", + "Crime Thriller", + "Heist film", + "Caper story", + "Crime Comedy", + "Comedy" + ], + "directed_by": [ + "Brett Ratner" + ], + "name": "After the Sunset", + "film_vector": [ + -0.514721691608429, + -0.21763451397418976, + -0.38085079193115234, + -0.006084732711315155, + -0.0671766996383667, + -0.14818695187568665, + -0.04655580222606659, + -0.10550262033939362, + -0.07912953197956085, + -0.16966651380062103 + ] + }, + { + "id": "/en/aftermath_2007", + "initial_release_date": "2013-03-01", + "genre": [ + "Crime Fiction", + "Thriller" + ], + "directed_by": [ + "Thomas Farone" + ], + "name": "Aftermath", + "film_vector": [ + -0.269622802734375, + -0.3903908431529999, + -0.03446793183684349, + -0.27496975660324097, + 0.15086489915847778, + -0.035180237144231796, + -0.0455716997385025, + -0.10305080562829971, + 0.03618687018752098, + -0.06917435675859451 + ] + }, + { + "id": "/en/against_the_ropes", + "initial_release_date": "2004-02-20", + "genre": [ + "Biographical film", + "Sports", + "Drama" + ], + "directed_by": [ + "Charles S. Dutton" + ], + "name": "Against the Ropes", + "film_vector": [ + -0.06131140887737274, + -0.03497857227921486, + -0.049777764827013016, + -0.11970267444849014, + 0.03766274452209473, + -0.2615179717540741, + -0.185034841299057, + -0.14255985617637634, + -0.0791555792093277, + -0.09415747225284576 + ] + }, + { + "id": "/en/agent_cody_banks_2_destination_london", + "initial_release_date": "2004-03-12", + "genre": [ + "Adventure Film", + "Action Film", + "Family", + "Action/Adventure", + "Spy film", + "Children's/Family", + "Family-Oriented Adventure", + "Comedy" + ], + "directed_by": [ + "Kevin Allen" + ], + "name": "Agent Cody Banks 2: Destination London", + "film_vector": [ + -0.2421354502439499, + -0.19116416573524475, + -0.1697116643190384, + 0.17372316122055054, + 0.13808591663837433, + -0.14225058257579803, + -0.10109807550907135, + -0.19715169072151184, + -0.12555965781211853, + -0.10014524310827255 + ] + }, + { + "id": "/en/agent_one-half", + "genre": [ + "Comedy" + ], + "directed_by": [ + "Brian Bero" + ], + "name": "Agent One-Half", + "film_vector": [ + 0.05918138846755028, + -0.10754051059484482, + -0.2793195843696594, + 0.0012874016538262367, + 0.16664916276931763, + -0.1809452623128891, + 0.1809123307466507, + -0.19716694951057434, + -0.09349287301301956, + -0.21250025928020477 + ] + }, + { + "id": "/en/agnes_and_his_brothers", + "initial_release_date": "2004-09-05", + "genre": [ + "Drama", + "Comedy" + ], + "directed_by": [ + "Oskar Roehler" + ], + "name": "Agnes and His Brothers", + "film_vector": [ + 0.07984955608844757, + 0.1306825429201126, + -0.2642101049423218, + -0.11719439923763275, + 0.0003558136522769928, + -0.03525494411587715, + 0.005282186903059483, + 0.03950812667608261, + 0.017253108322620392, + -0.4206380248069763 + ] + }, + { + "id": "/en/aideista_parhain", + "initial_release_date": "2005-08-25", + "genre": [ + "War film", + "Drama" + ], + "directed_by": [ + "Klaus H\u00e4r\u00f6" + ], + "name": "Mother of Mine", + "film_vector": [ + -0.10026441514492035, + 0.004470808431506157, + 0.03347339481115341, + -0.01701086014509201, + 0.23149339854717255, + -0.23689475655555725, + -0.12147444486618042, + -0.003652093932032585, + -0.021567141637206078, + -0.24566900730133057 + ] + }, + { + "id": "/en/aileen_life_and_death_of_a_serial_killer", + "initial_release_date": "2003-05-10", + "genre": [ + "Documentary film", + "Crime Fiction", + "Political drama" + ], + "directed_by": [ + "Nick Broomfield", + "Joan Churchill" + ], + "name": "Aileen: Life and Death of a Serial Killer", + "film_vector": [ + -0.18085001409053802, + -0.20554369688034058, + 0.04175986349582672, + -0.2858428955078125, + 0.05497142672538757, + -0.20015914738178253, + -0.01804848201572895, + -0.0374944731593132, + 0.17750519514083862, + -0.21962714195251465 + ] + }, + { + "id": "/en/air_2005", + "initial_release_date": "2005-02-05", + "genre": [ + "Fantasy", + "Anime", + "Animation", + "Japanese Movies", + "Drama" + ], + "directed_by": [ + "Osamu Dezaki" + ], + "name": "Air", + "film_vector": [ + -0.38671594858169556, + 0.2152889370918274, + 0.06922100484371185, + 0.2613358497619629, + -0.3130373954772949, + 0.18325041234493256, + -0.07267266511917114, + -0.03388317674398422, + 0.19268688559532166, + -0.11617372930049896 + ] + }, + { + "id": "/en/air_bud_seventh_inning_fetch", + "initial_release_date": "2002-02-21", + "genre": [ + "Family", + "Sports", + "Comedy", + "Drama" + ], + "directed_by": [ + "Robert Vince" + ], + "name": "Air Bud: Seventh Inning Fetch", + "film_vector": [ + 0.08883806318044662, + 0.09228489547967911, + -0.19917841255664825, + -0.04853500798344612, + -0.24947333335876465, + 0.14036718010902405, + -0.06491634249687195, + -0.20100590586662292, + -0.031221814453601837, + 0.061456985771656036 + ] + }, + { + "id": "/en/air_bud_spikes_back", + "initial_release_date": "2003-06-24", + "genre": [ + "Family", + "Sports", + "Comedy" + ], + "directed_by": [ + "Mike Southon" + ], + "name": "Air Bud: Spikes Back", + "film_vector": [ + 0.21104106307029724, + -0.012707475572824478, + -0.19507470726966858, + -0.016967376694083214, + -0.26579248905181885, + -0.0009109340608119965, + -0.04154104366898537, + -0.2326420545578003, + 0.013119962066411972, + 0.03091386705636978 + ] + }, + { + "id": "/en/air_buddies", + "initial_release_date": "2006-12-10", + "genre": [ + "Family", + "Animal Picture", + "Children's/Family", + "Family-Oriented Adventure", + "Comedy" + ], + "directed_by": [ + "Robert Vince" + ], + "name": "Air Buddies", + "film_vector": [ + -0.019783293828368187, + 0.0349050834774971, + -0.28743594884872437, + 0.4423333406448364, + -0.2923951745033264, + 0.15854895114898682, + -0.06835821270942688, + -0.18690776824951172, + 0.09361683577299118, + -0.09540055692195892 + ] + }, + { + "id": "/en/aitraaz", + "initial_release_date": "2004-11-12", + "genre": [ + "Trial drama", + "Thriller", + "Bollywood", + "World cinema", + "Drama" + ], + "directed_by": [ + "Abbas Burmawalla", + "Mustan Burmawalla" + ], + "name": "Aitraaz", + "film_vector": [ + -0.5827001333236694, + 0.18991413712501526, + -0.06797662377357483, + -0.19023951888084412, + -0.0222814679145813, + -0.06978347897529602, + 0.10611532628536224, + -0.11635956913232803, + 0.0489879846572876, + -0.10828594863414764 + ] + }, + { + "id": "/en/aka_2002", + "initial_release_date": "2002-01-19", + "genre": [ + "LGBT", + "Indie film", + "Historical period drama", + "Drama" + ], + "directed_by": [ + "Duncan Roy" + ], + "name": "AKA", + "film_vector": [ + -0.34260982275009155, + 0.1649656891822815, + -0.30864840745925903, + -0.0950808897614479, + -0.16371285915374756, + -0.13395525515079498, + -0.14768248796463013, + 0.03420611470937729, + 0.30226385593414307, + -0.2696382999420166 + ] + }, + { + "id": "/en/aakasha_gopuram", + "initial_release_date": "2008-08-22", + "genre": [ + "Romance Film", + "Drama", + "Malayalam Cinema", + "World cinema" + ], + "directed_by": [ + "K.P.Kumaran" + ], + "name": "Aakasha Gopuram", + "film_vector": [ + -0.519260048866272, + 0.378897100687027, + -0.055397458374500275, + 0.05343092605471611, + 0.09764327108860016, + -0.12149611115455627, + 0.09799067676067352, + -0.05103505030274391, + 0.05596302077174187, + -0.11444316059350967 + ] + }, + { + "id": "/en/akbar-jodha", + "initial_release_date": "2008-02-13", + "genre": [ + "Biographical film", + "Romance Film", + "Musical", + "World cinema", + "Adventure Film", + "Action Film", + "Historical fiction", + "Musical Drama", + "Drama" + ], + "directed_by": [ + "Ashutosh Gowariker" + ], + "name": "Jodhaa Akbar", + "film_vector": [ + -0.5220209956169128, + 0.26057660579681396, + -0.10890762507915497, + 0.005756653845310211, + 0.028890356421470642, + -0.23515576124191284, + -0.03643423318862915, + 0.1452433168888092, + -0.10723346471786499, + -0.04965835437178612 + ] + }, + { + "id": "/en/akeelah_and_the_bee", + "initial_release_date": "2006-03-16", + "genre": [ + "Drama" + ], + "directed_by": [ + "Doug Atchison" + ], + "name": "Akeelah and the Bee", + "film_vector": [ + 0.18472504615783691, + 0.10263165831565857, + -0.10112585872411728, + -0.17650866508483887, + 0.017769895493984222, + 0.14658182859420776, + -0.017567118629813194, + 0.10581429302692413, + 0.005445822607725859, + 0.03605923056602478 + ] + }, + { + "id": "/en/aks", + "initial_release_date": "2001-07-13", + "genre": [ + "Horror", + "Thriller", + "Mystery", + "Bollywood", + "World cinema" + ], + "directed_by": [ + "Rakeysh Omprakash Mehra" + ], + "name": "The Reflection", + "film_vector": [ + -0.5919820070266724, + 0.011880860663950443, + -0.06186307966709137, + 0.058905817568302155, + -0.017565054818987846, + -0.10521046817302704, + 0.20742781460285187, + 0.013319211080670357, + 0.15139013528823853, + -0.1289273351430893 + ] + }, + { + "id": "/en/aksar", + "initial_release_date": "2006-02-03", + "genre": [ + "Romance Film", + "World cinema", + "Thriller", + "Drama" + ], + "directed_by": [ + "Anant Mahadevan" + ], + "name": "Aksar", + "film_vector": [ + -0.6242115497589111, + 0.21177628636360168, + -0.12394140660762787, + -0.008607074618339539, + 0.14411482214927673, + -0.08767393231391907, + 0.09765958040952682, + -0.11721604317426682, + 0.07331773638725281, + -0.10190828144550323 + ] + }, + { + "id": "/en/al_franken_god_spoke", + "initial_release_date": "2006-09-13", + "genre": [ + "Mockumentary", + "Documentary film", + "Political cinema", + "Culture & Society", + "Biographical film" + ], + "directed_by": [ + "Nick Doob", + "Chris Hegedus" + ], + "name": "Al Franken: God Spoke", + "film_vector": [ + -0.09292788058519363, + 0.014313288033008575, + -0.19258838891983032, + -0.04203903675079346, + -0.2369830459356308, + -0.44895821809768677, + -0.06076964735984802, + -0.009422596544027328, + 0.04389683157205582, + -0.0927431657910347 + ] + }, + { + "id": "/en/alag", + "initial_release_date": "2006-06-16", + "genre": [ + "Thriller", + "Science Fiction", + "Bollywood", + "World cinema" + ], + "directed_by": [ + "Ashu Trikha" + ], + "name": "Different", + "film_vector": [ + -0.7556622624397278, + 0.016512077301740646, + -0.03461972624063492, + 0.0691692978143692, + -0.0992739349603653, + -0.07573817670345306, + 0.15625707805156708, + -0.15533098578453064, + 0.12236493825912476, + -0.09585033357143402 + ] + }, + { + "id": "/en/alai", + "initial_release_date": "2003-09-10", + "genre": [ + "Romance Film", + "Drama", + "Comedy", + "Tamil cinema", + "World cinema" + ], + "directed_by": [ + "Vikram Kumar" + ], + "name": "Wave", + "film_vector": [ + -0.6178056597709656, + 0.3813146948814392, + -0.09260421246290207, + 0.0668983906507492, + -0.04619421064853668, + -0.13800418376922607, + 0.07986370474100113, + -0.0003087427467107773, + 0.08675049245357513, + -0.13137564063072205 + ] + }, + { + "id": "/en/alaipayuthey", + "initial_release_date": "2000-04-14", + "genre": [ + "Musical", + "Romance Film", + "Musical Drama", + "Drama" + ], + "directed_by": [ + "Mani Ratnam" + ], + "name": "Waves", + "film_vector": [ + -0.34591376781463623, + 0.10836774110794067, + -0.3599191904067993, + 0.01846657320857048, + -0.013630678877234459, + -0.07439684122800827, + -0.2216503620147705, + 0.2100580632686615, + 0.1344008445739746, + -0.03727993369102478 + ] + }, + { + "id": "/en/alatriste", + "initial_release_date": "2006-09-01", + "genre": [ + "Thriller", + "War film", + "Adventure Film", + "Action Film", + "Drama", + "Historical fiction" + ], + "directed_by": [ + "Agust\u00edn D\u00edaz Yanes" + ], + "name": "Alatriste", + "film_vector": [ + -0.7339195609092712, + -0.018023692071437836, + -0.16262215375900269, + 0.05639395862817764, + -0.14818593859672546, + -0.17054790258407593, + -0.07728126645088196, + -0.03144935891032219, + 0.0134737528860569, + -0.1782500445842743 + ] + }, + { + "id": "/en/alex_emma", + "initial_release_date": "2003-06-20", + "genre": [ + "Romantic comedy", + "Romance Film", + "Comedy" + ], + "directed_by": [ + "Rob Reiner" + ], + "name": "Alex & Emma", + "film_vector": [ + -0.1331627517938614, + 0.0833812728524208, + -0.48915743827819824, + 0.1388235092163086, + 0.3005811274051666, + -0.012922285124659538, + -0.07260571420192719, + -0.05252446234226227, + 0.13186615705490112, + -0.12318955361843109 + ] + }, + { + "id": "/en/alexander_2004", + "initial_release_date": "2004-11-16", + "genre": [ + "War film", + "Action Film", + "Adventure Film", + "Romance Film", + "Biographical film", + "Historical fiction", + "Drama" + ], + "directed_by": [ + "Oliver Stone", + "Wilhelm Sasnal", + "Anka Sasnal" + ], + "name": "Alexander", + "film_vector": [ + -0.5374875068664551, + 0.12624947726726532, + -0.10020005702972412, + 0.10081426054239273, + -0.04834253340959549, + -0.2541041672229767, + -0.26101529598236084, + 0.0014914488419890404, + -0.11693549156188965, + -0.21824783086776733 + ] + }, + { + "id": "/en/alexandras_project", + "genre": [ + "Thriller", + "Suspense", + "Psychological thriller", + "Indie film", + "World cinema", + "Drama" + ], + "directed_by": [ + "Rolf de Heer" + ], + "name": "Alexandra's Project", + "film_vector": [ + -0.4866262376308441, + -0.09243950992822647, + -0.11842745542526245, + -0.09557367116212845, + 0.08705046772956848, + -0.0496075339615345, + -0.04598044604063034, + -0.03217877075076103, + 0.2676753103733063, + -0.07678017020225525 + ] + }, + { + "id": "/en/alfie_2004", + "initial_release_date": "2004-10-22", + "genre": [ + "Sex comedy", + "Remake", + "Comedy-drama", + "Romance Film", + "Romantic comedy", + "Comedy", + "Drama" + ], + "directed_by": [ + "Charles Shyer" + ], + "name": "Alfie", + "film_vector": [ + -0.16104000806808472, + 0.05990496650338173, + -0.4814569354057312, + 0.17123684287071228, + 0.1305822730064392, + -0.126278817653656, + 0.03678219020366669, + 0.08250714838504791, + -0.03429783880710602, + -0.12392482161521912 + ] + }, + { + "id": "/en/ali_2001", + "initial_release_date": "2001-12-11", + "genre": [ + "Biographical film", + "Sports", + "Historical period drama", + "Sports films", + "Drama" + ], + "directed_by": [ + "Michael Mann" + ], + "name": "Ali", + "film_vector": [ + -0.3639605641365051, + 0.20525884628295898, + -0.026665151119232178, + -0.1236799955368042, + -0.09063340723514557, + -0.22275389730930328, + -0.14247462153434753, + -0.054986681789159775, + -0.15345361828804016, + -0.18772682547569275 + ] + }, + { + "id": "/en/ali_g_indahouse", + "initial_release_date": "2002-03-22", + "genre": [ + "Stoner film", + "Parody", + "Gross out", + "Gross-out film", + "Comedy" + ], + "directed_by": [ + "Mark Mylod" + ], + "name": "Ali G Indahouse", + "film_vector": [ + -0.08226508647203445, + -0.023247770965099335, + -0.269523024559021, + 0.10500150918960571, + 0.02697567269206047, + -0.3455398678779602, + 0.24093084037303925, + 0.004752914421260357, + -0.06746617704629898, + -0.05372723937034607 + ] + }, + { + "id": "/en/alien_autopsy_2006", + "initial_release_date": "2006-04-07", + "genre": [ + "Science Fiction", + "Mockumentary", + "Comedy" + ], + "directed_by": [ + "Jonny Campbell" + ], + "name": "Alien Autopsy", + "film_vector": [ + -0.050615645945072174, + -0.2631191909313202, + -0.07868560403585434, + 0.03273997828364372, + 0.04284391552209854, + -0.2666590213775635, + 0.34716781973838806, + 0.0025635994970798492, + -0.0016856975853443146, + -0.06543552130460739 + ] + }, + { + "id": "/en/avp_alien_vs_predator", + "initial_release_date": "2004-08-12", + "genre": [ + "Science Fiction", + "Horror", + "Action Film", + "Monster movie", + "Thriller", + "Adventure Film" + ], + "directed_by": [ + "Paul W. S. Anderson" + ], + "name": "Alien vs. Predator", + "film_vector": [ + -0.44061803817749023, + -0.3095717430114746, + -0.02571761980652809, + 0.3079710006713867, + 0.022989176213741302, + -0.19390396773815155, + -0.022582875564694405, + -0.0040480284951627254, + -0.12069445848464966, + 0.06887448579072952 + ] + }, + { + "id": "/en/avpr_aliens_vs_predator_requiem", + "initial_release_date": "2007-12-25", + "genre": [ + "Science Fiction", + "Action Film", + "Action/Adventure", + "Horror", + "Monster movie", + "Thriller" + ], + "directed_by": [ + "Colin Strause", + "Greg Strause" + ], + "name": "AVPR: Aliens vs Predator - Requiem", + "film_vector": [ + -0.32954245805740356, + -0.33354127407073975, + 0.053720053285360336, + 0.2679670751094818, + 0.1864725947380066, + -0.1835184097290039, + -0.008568285033106804, + -0.00607222318649292, + -0.020947448909282684, + 0.07936366647481918 + ] + }, + { + "id": "/en/aliens_of_the_deep", + "initial_release_date": "2005-01-28", + "genre": [ + "Documentary film", + "Travel", + "Education", + "Biological Sciences" + ], + "directed_by": [ + "James Cameron", + "Steven Quale", + "Steven Quale" + ], + "name": "Aliens of the Deep", + "film_vector": [ + -0.10621180385351181, + 0.004200540482997894, + 0.19000479578971863, + 0.09246480464935303, + -0.08399311453104019, + -0.24907976388931274, + -0.020343294367194176, + 0.10475577414035797, + 0.11797545850276947, + 0.008017461746931076 + ] + }, + { + "id": "/en/alive_2002", + "initial_release_date": "2002-09-12", + "genre": [ + "Science Fiction", + "Action Film", + "Horror", + "Thriller", + "World cinema", + "Action/Adventure", + "Japanese Movies" + ], + "directed_by": [ + "Ryuhei Kitamura" + ], + "name": "Alive", + "film_vector": [ + -0.5892111659049988, + -0.06221134215593338, + -0.0066252294927835464, + 0.2165549099445343, + -0.21173886954784393, + -0.05276227369904518, + 0.016964903101325035, + -0.10131333768367767, + 0.17351754009723663, + -0.12215910851955414 + ] + }, + { + "id": "/en/all_about_lily_chou-chou", + "initial_release_date": "2001-09-07", + "genre": [ + "Crime Fiction", + "Musical", + "Thriller", + "Art film", + "Romance Film", + "Drama", + "Musical Drama" + ], + "directed_by": [ + "Shunji Iwai" + ], + "name": "All About Lily Chou-Chou", + "film_vector": [ + -0.385575532913208, + 0.08622540533542633, + -0.280331552028656, + -0.004601124674081802, + 0.19088239967823029, + -0.035315655171871185, + -0.03344545513391495, + 0.029498465359210968, + 0.1492317020893097, + -0.196111798286438 + ] + }, + { + "id": "/en/all_about_the_benjamins", + "initial_release_date": "2002-03-08", + "genre": [ + "Action Film", + "Crime Fiction", + "Comedy", + "Thriller" + ], + "directed_by": [ + "Kevin Bray" + ], + "name": "All About the Benjamins", + "film_vector": [ + -0.23450663685798645, + -0.17353218793869019, + -0.31436866521835327, + 0.09422507882118225, + -0.02915763109922409, + -0.15032699704170227, + -0.08032278716564178, + -0.2214396893978119, + -0.003053121268749237, + -0.26458919048309326 + ] + }, + { + "id": "/en/all_i_want_2002", + "initial_release_date": "2002-09-10", + "genre": [ + "Romantic comedy", + "Coming of age", + "Romance Film", + "Comedy" + ], + "directed_by": [ + "Jeffrey Porter" + ], + "name": "All I Want", + "film_vector": [ + -0.3889273405075073, + 0.2339152842760086, + -0.43274104595184326, + 0.14685963094234467, + 0.11096858233213425, + -0.03401946648955345, + 0.08473274856805801, + -0.14103612303733826, + 0.16895665228366852, + -0.12942540645599365 + ] + }, + { + "id": "/en/all_over_the_guy", + "genre": [ + "Indie film", + "LGBT", + "Romantic comedy", + "Romance Film", + "Gay", + "Gay Interest", + "Gay Themed", + "Comedy" + ], + "directed_by": [ + "Julie Davis" + ], + "name": "All Over the Guy", + "film_vector": [ + -0.28857657313346863, + 0.07028081268072128, + -0.5734816789627075, + 0.06934548914432526, + -0.06652132421731949, + -0.1582997441291809, + -0.09031383693218231, + 0.07886309921741486, + 0.08240842819213867, + -0.004258045926690102 + ] + }, + { + "id": "/en/all_souls_day_2005", + "initial_release_date": "2005-01-25", + "genre": [ + "Horror", + "Supernatural", + "Zombie Film" + ], + "directed_by": [ + "Jeremy Kasten", + "Mark A. Altman" + ], + "name": "All Souls Day", + "film_vector": [ + -0.21673321723937988, + -0.3509371280670166, + -0.06561236083507538, + 0.20720024406909943, + 0.2495744377374649, + -0.1727476269006729, + 0.19740831851959229, + 0.06075755134224892, + 0.20000791549682617, + -0.0770951509475708 + ] + }, + { + "id": "/en/all_the_kings_men_2006", + "initial_release_date": "2006-09-10", + "genre": [ + "Political drama", + "Thriller" + ], + "directed_by": [ + "Steven Zaillian" + ], + "name": "All the King's Men", + "film_vector": [ + -0.24033036828041077, + -0.11470435559749603, + -0.20055314898490906, + -0.15864849090576172, + 0.024484263733029366, + -0.09862203896045685, + -0.12977007031440735, + -0.06166020780801773, + -0.06912292540073395, + -0.2247973084449768 + ] + }, + { + "id": "/en/all_the_real_girls", + "initial_release_date": "2003-01-19", + "genre": [ + "Romance Film", + "Indie film", + "Coming of age", + "Drama" + ], + "directed_by": [ + "David Gordon Green" + ], + "name": "All the Real Girls", + "film_vector": [ + -0.47621774673461914, + 0.16434301435947418, + -0.35124266147613525, + 0.10887520015239716, + 0.096934974193573, + -0.03530552238225937, + -0.04056660830974579, + -0.1987776756286621, + 0.3608531951904297, + -0.05610135942697525 + ] + }, + { + "id": "/en/allari_bullodu", + "genre": [ + "Comedy", + "Romance Film", + "Tollywood", + "World cinema" + ], + "directed_by": [ + "Kovelamudi Raghavendra Rao" + ], + "name": "Allari Bullodu", + "film_vector": [ + -0.43841078877449036, + 0.380196213722229, + -0.07143071293830872, + 0.12727853655815125, + 0.10242959856987, + -0.16851098835468292, + 0.16250255703926086, + -0.14576131105422974, + 0.01853114180266857, + -0.14375093579292297 + ] + }, + { + "id": "/en/allari_pidugu", + "initial_release_date": "2005-10-05", + "genre": [ + "Drama", + "Tollywood", + "World cinema" + ], + "directed_by": [ + "Jayant Paranji" + ], + "name": "Allari Pidugu", + "film_vector": [ + -0.4956057667732239, + 0.43140721321105957, + 0.047483645379543304, + -0.016113318502902985, + -0.011865285225212574, + -0.10600296407938004, + 0.12574651837348938, + -0.09061362594366074, + 0.07050792872905731, + -0.18617656826972961 + ] + }, + { + "id": "/en/alles_auf_zucker", + "initial_release_date": "2004-12-31", + "genre": [ + "Comedy" + ], + "directed_by": [ + "Dani Levy" + ], + "name": "Alles auf Zucker!", + "film_vector": [ + 0.13744425773620605, + 0.05449344590306282, + -0.27328556776046753, + 0.018019871786236763, + -0.11786539852619171, + -0.14102765917778015, + 0.2951970100402832, + -0.06928372383117676, + -0.05582248792052269, + -0.10189604759216309 + ] + }, + { + "id": "/en/alley_cats_strike", + "initial_release_date": "2000-03-18", + "genre": [ + "Family", + "Sports" + ], + "directed_by": [ + "Rod Daniel" + ], + "name": "Alley Cats Strike!", + "film_vector": [ + 0.1391954869031906, + -0.10044605284929276, + -0.08330662548542023, + -0.0005961395800113678, + -0.13461777567863464, + 0.14971835911273956, + 0.0036363271065056324, + -0.12545464932918549, + 0.04040580987930298, + 0.08017943054437637 + ] + }, + { + "id": "/en/almost_famous", + "initial_release_date": "2000-09-08", + "genre": [ + "Musical", + "Comedy-drama", + "Musical Drama", + "Road movie", + "Musical comedy", + "Comedy", + "Music", + "Drama" + ], + "directed_by": [ + "Cameron Crowe" + ], + "name": "Almost Famous", + "film_vector": [ + -0.23542064428329468, + 0.06198980659246445, + -0.5439538955688477, + 0.05135323852300644, + -0.1261506825685501, + -0.19485235214233398, + -0.20258396863937378, + 0.19550225138664246, + -0.05216587334871292, + 0.023777306079864502 + ] + }, + { + "id": "/en/almost_round_three", + "initial_release_date": "2004-11-10", + "genre": [ + "Sports" + ], + "directed_by": [ + "Matt Hill", + "Matt Hill" + ], + "name": "Almost: Round Three", + "film_vector": [ + 0.07749344408512115, + -0.06140492111444473, + -0.06150394678115845, + -0.06862058490514755, + -0.2027701437473297, + 0.05011047050356865, + -0.17241844534873962, + -0.14214976131916046, + -0.09297232329845428, + 0.20205315947532654 + ] + }, + { + "id": "/en/alone_and_restless", + "genre": [ + "Drama" + ], + "directed_by": [ + "Michael Thomas Dunn" + ], + "name": "Alone and Restless", + "film_vector": [ + -0.00966501422226429, + -0.05527578294277191, + -0.22045597434043884, + -0.24189606308937073, + 0.13993632793426514, + 0.22919994592666626, + -0.03320128843188286, + -0.02077914960682392, + 0.13842834532260895, + -0.02702583745121956 + ] + }, + { + "id": "/en/alone_in_the_dark", + "initial_release_date": "2005-01-28", + "genre": [ + "Science Fiction", + "Horror", + "Action Film", + "Thriller", + "B movie", + "Action/Adventure" + ], + "directed_by": [ + "Uwe Boll" + ], + "name": "Alone in the Dark", + "film_vector": [ + -0.5245915651321411, + -0.3348419964313507, + -0.19670873880386353, + 0.18023329973220825, + 0.061809372156858444, + -0.1052388846874237, + 0.05993563309311867, + -0.059843510389328, + 0.1275666058063507, + -0.15249717235565186 + ] + }, + { + "id": "/en/along_came_polly", + "initial_release_date": "2004-01-12", + "genre": [ + "Romantic comedy", + "Romance Film", + "Gross out", + "Gross-out film", + "Comedy" + ], + "directed_by": [ + "John Hamburg" + ], + "name": "Along Came Polly", + "film_vector": [ + -0.17604216933250427, + -0.030388688668608665, + -0.4935140013694763, + 0.1461324691772461, + 0.11435969173908234, + -0.21235297620296478, + 0.08658172190189362, + 0.19771328568458557, + -0.04171191155910492, + -0.04163716733455658 + ] + }, + { + "id": "/en/alpha_dog", + "initial_release_date": "2006-01-27", + "genre": [ + "Crime Fiction", + "Biographical film", + "Drama" + ], + "directed_by": [ + "Nick Cassavetes" + ], + "name": "Alpha Dog", + "film_vector": [ + -0.3091174066066742, + -0.23851385712623596, + -0.07097920775413513, + -0.040978409349918365, + -0.08891208469867706, + -0.16156135499477386, + -0.12316742539405823, + -0.22081799805164337, + -0.05787041038274765, + -0.270813524723053 + ] + }, + { + "id": "/en/amelie", + "initial_release_date": "2001-04-25", + "genre": [ + "Romance Film", + "Comedy" + ], + "directed_by": [ + "Jean-Pierre Jeunet" + ], + "name": "Am\u00e9lie", + "film_vector": [ + -0.1060064435005188, + 0.041083965450525284, + -0.27740317583084106, + 0.13167911767959595, + 0.39922791719436646, + -0.0951579362154007, + -0.028498096391558647, + 0.07076187431812286, + 0.17367896437644958, + -0.3067059814929962 + ] + }, + { + "id": "/en/america_freedom_to_fascism", + "initial_release_date": "2006-07-28", + "genre": [ + "Documentary film", + "Political cinema", + "Culture & Society" + ], + "directed_by": [ + "Aaron Russo" + ], + "name": "America: Freedom to Fascism", + "film_vector": [ + -0.0973304882645607, + -0.004440200515091419, + 0.06962483376264572, + -0.11477306485176086, + -0.13868476450443268, + -0.3997814655303955, + -0.1491752415895462, + -0.07227352261543274, + 0.22597849369049072, + -0.18980231881141663 + ] + }, + { + "id": "/en/americas_sweethearts", + "initial_release_date": "2001-07-17", + "genre": [ + "Romantic comedy", + "Romance Film", + "Comedy" + ], + "directed_by": [ + "Joe Roth" + ], + "name": "America's Sweethearts", + "film_vector": [ + -0.07332172244787216, + 0.07873734831809998, + -0.5581204295158386, + 0.11693350970745087, + 0.20214757323265076, + -0.05120885744690895, + -0.09973303973674774, + -0.13764800131320953, + 0.027218714356422424, + -0.18723583221435547 + ] + }, + { + "id": "/en/american_cowslip", + "initial_release_date": "2009-07-24", + "genre": [ + "Black comedy", + "Indie film", + "Comedy" + ], + "directed_by": [ + "Mark David" + ], + "name": "American Cowslip", + "film_vector": [ + -0.11990523338317871, + -0.061056703329086304, + -0.3544662594795227, + 0.05871308594942093, + -0.05229835584759712, + -0.29285377264022827, + 0.20938877761363983, + -0.17439553141593933, + 0.14524921774864197, + -0.1427384912967682 + ] + }, + { + "id": "/en/american_desi", + "genre": [ + "Indie film", + "Romance Film", + "Romantic comedy", + "Musical comedy", + "Teen film", + "Comedy" + ], + "directed_by": [ + "Piyush Dinker Pandya" + ], + "name": "American Desi", + "film_vector": [ + -0.45945626497268677, + 0.15019235014915466, + -0.5281389951705933, + 0.14678578078746796, + 0.04070155322551727, + -0.23531180620193481, + 0.04771187901496887, + -0.09174343943595886, + 0.1316729336977005, + -0.0009007267653942108 + ] + }, + { + "id": "/en/american_dog", + "initial_release_date": "2008-11-17", + "genre": [ + "Family", + "Adventure Film", + "Animation", + "Comedy" + ], + "directed_by": [ + "Chris Williams", + "Byron Howard" + ], + "name": "Bolt", + "film_vector": [ + -0.09022854268550873, + 0.015522495843470097, + -0.12420469522476196, + 0.4597005546092987, + -0.22124698758125305, + -0.02173726260662079, + 0.0012798579409718513, + -0.20194143056869507, + 0.02572854422032833, + -0.18286117911338806 + ] + }, + { + "id": "/en/american_dreamz", + "initial_release_date": "2006-04-21", + "genre": [ + "Political cinema", + "Parody", + "Political satire", + "Media Satire", + "Comedy" + ], + "directed_by": [ + "Paul Weitz" + ], + "name": "American Dreamz", + "film_vector": [ + -0.10675975680351257, + 0.09262802451848984, + -0.29341921210289, + -0.04600697010755539, + -0.39952850341796875, + -0.2633226215839386, + 0.08805122971534729, + 0.02077120915055275, + 0.11621768772602081, + -0.1185515820980072 + ] + }, + { + "id": "/en/american_gangster", + "initial_release_date": "2007-10-19", + "genre": [ + "Crime Fiction", + "War film", + "Crime Thriller", + "Historical period drama", + "Biographical film", + "Crime Drama", + "Gangster Film", + "True crime", + "Drama" + ], + "directed_by": [ + "Ridley Scott" + ], + "name": "American Gangster", + "film_vector": [ + -0.5373713970184326, + -0.172756165266037, + -0.32911375164985657, + -0.14959847927093506, + -0.25434982776641846, + -0.2641783356666565, + -0.08636355400085449, + -0.01645955815911293, + -0.14519032835960388, + -0.12014038860797882 + ] + }, + { + "id": "/en/american_gun", + "initial_release_date": "2005-09-15", + "genre": [ + "Indie film", + "Drama" + ], + "directed_by": [ + "Aric Avelino" + ], + "name": "American Gun", + "film_vector": [ + -0.20966556668281555, + -0.22167009115219116, + -0.1525869220495224, + 0.02386300452053547, + 0.1988610327243805, + -0.31696590781211853, + -0.08615061640739441, + -0.31991928815841675, + 0.06819526851177216, + -0.19783347845077515 + ] + }, + { + "id": "/en/american_hardcore_2006", + "initial_release_date": "2006-03-11", + "genre": [ + "Music", + "Documentary film", + "Rockumentary", + "Punk rock", + "Biographical film" + ], + "directed_by": [ + "Paul Rachman" + ], + "name": "American Hardcore", + "film_vector": [ + -0.3581400513648987, + -0.13811583817005157, + -0.18450303375720978, + 0.055471234023571014, + -0.2681592106819153, + -0.46560990810394287, + -0.0512806698679924, + -0.10366016626358032, + 0.21473518013954163, + 0.04287714138627052 + ] + }, + { + "id": "/en/american_outlaws", + "initial_release_date": "2001-08-17", + "genre": [ + "Western", + "Costume drama", + "Action/Adventure", + "Action Film", + "Revisionist Western", + "Comedy Western", + "Comedy" + ], + "directed_by": [ + "Les Mayfield" + ], + "name": "American Outlaws", + "film_vector": [ + -0.28155314922332764, + -0.08642979711294174, + -0.259458065032959, + 0.15228280425071716, + -0.31075814366340637, + -0.2610311508178711, + -0.09935048222541809, + -0.054866380989551544, + -0.12917660176753998, + -0.234302818775177 + ] + }, + { + "id": "/en/american_pie_the_naked_mile", + "initial_release_date": "2006-12-07", + "genre": [ + "Comedy" + ], + "directed_by": [ + "Joe Nussbaum" + ], + "name": "American Pie Presents: The Naked Mile", + "film_vector": [ + 0.18812352418899536, + 0.0006118007004261017, + -0.3586030900478363, + 0.1295153796672821, + 0.07337059825658798, + -0.22640351951122284, + 0.11908837407827377, + -0.11878032982349396, + 0.014717062935233116, + -0.08853553235530853 + ] + }, + { + "id": "/en/american_pie_2", + "initial_release_date": "2001-08-06", + "genre": [ + "Romance Film", + "Comedy" + ], + "directed_by": [ + "James B. Rogers" + ], + "name": "American Pie 2", + "film_vector": [ + -0.13793325424194336, + -0.030027318745851517, + -0.4169856011867523, + 0.22018495202064514, + 0.322767049074173, + -0.1482931524515152, + -0.049597226083278656, + -0.22919116914272308, + 0.016930466517806053, + -0.04649265855550766 + ] + }, + { + "id": "/en/american_pie_presents_band_camp", + "initial_release_date": "2005-10-31", + "genre": [ + "Comedy" + ], + "directed_by": [ + "Steve Rash" + ], + "name": "American Pie Presents: Band Camp", + "film_vector": [ + 0.2812991738319397, + 0.017809776589274406, + -0.3406899571418762, + 0.1399671733379364, + -0.07327206432819366, + -0.19786636531352997, + 0.095591239631176, + -0.08219476044178009, + 0.030970647931098938, + -0.009663404896855354 + ] + }, + { + "id": "/en/american_psycho_2000", + "initial_release_date": "2000-01-21", + "genre": [ + "Black comedy", + "Slasher", + "Thriller", + "Horror", + "Psychological thriller", + "Crime Fiction", + "Horror comedy", + "Comedy", + "Drama" + ], + "directed_by": [ + "Mary Harron" + ], + "name": "American Psycho", + "film_vector": [ + -0.4691590368747711, + -0.34924644231796265, + -0.459575891494751, + -0.038058068603277206, + -0.1203676089644432, + -0.17026099562644958, + 0.10670170187950134, + 0.18002945184707642, + -0.024314606562256813, + -0.026323365047574043 + ] + }, + { + "id": "/en/american_splendor_2003", + "initial_release_date": "2003-01-20", + "genre": [ + "Indie film", + "Biographical film", + "Comedy-drama", + "Marriage Drama", + "Comedy", + "Drama" + ], + "directed_by": [ + "Shari Springer Berman", + "Robert Pulcini" + ], + "name": "American Splendor", + "film_vector": [ + -0.32902991771698, + 0.025777317583560944, + -0.5104342699050903, + -0.021794835105538368, + -0.0863126590847969, + -0.2948180139064789, + -0.09274543821811676, + -0.0007522259838879108, + 0.10753750056028366, + -0.1928592324256897 + ] + }, + { + "id": "/en/american_wedding", + "initial_release_date": "2003-07-24", + "genre": [ + "Romance Film", + "Comedy" + ], + "directed_by": [ + "Jesse Dylan" + ], + "name": "American Wedding", + "film_vector": [ + -0.02489558979868889, + 0.041732385754585266, + -0.46300801634788513, + 0.09466215968132019, + 0.38971585035324097, + -0.18153414130210876, + -0.006499468814581633, + -0.10956044495105743, + -0.011795835569500923, + -0.19361290335655212 + ] + }, + { + "id": "/en/americano_2005", + "initial_release_date": "2005-01-07", + "genre": [ + "Romance Film", + "Comedy", + "Drama" + ], + "directed_by": [ + "Kevin Noland" + ], + "name": "Americano", + "film_vector": [ + -0.3657638132572174, + 0.030056051909923553, + -0.48467689752578735, + 0.1078338474035263, + 0.20497184991836548, + -0.1117430180311203, + -0.046036191284656525, + -0.2295030951499939, + 0.12367675453424454, + -0.21263179183006287 + ] + }, + { + "id": "/en/amma_nanna_o_tamila_ammayi", + "initial_release_date": "2003-04-19", + "genre": [ + "Sports", + "Tollywood", + "World cinema", + "Drama" + ], + "directed_by": [ + "Puri Jagannadh" + ], + "name": "Amma Nanna O Tamila Ammayi", + "film_vector": [ + -0.427651047706604, + 0.4425612688064575, + 0.10330432653427124, + -0.05156690627336502, + -0.07508623600006104, + -0.0025339843705296516, + 0.04730363190174103, + -0.12379680573940277, + 0.0026360340416431427, + -0.003961969632655382 + ] + }, + { + "id": "/en/amores_perros", + "initial_release_date": "2000-05-14", + "genre": [ + "Thriller", + "Drama" + ], + "directed_by": [ + "Alejandro Gonz\u00e1lez I\u00f1\u00e1rritu" + ], + "name": "Amores perros", + "film_vector": [ + -0.2887175679206848, + -0.12056873738765717, + -0.17082831263542175, + -0.06033138930797577, + 0.32295113801956177, + 0.00938432291150093, + -0.12756603956222534, + -0.039041683077812195, + 0.07831624150276184, + -0.15910333395004272 + ] + }, + { + "id": "/en/amrutham", + "initial_release_date": "2004-12-24", + "genre": [ + "Drama", + "Malayalam Cinema", + "World cinema" + ], + "directed_by": [ + "Sibi Malayil" + ], + "name": "Amrutham", + "film_vector": [ + -0.5645273923873901, + 0.3940053880214691, + 0.06714767217636108, + -0.0458848737180233, + -0.07434049248695374, + -0.12681400775909424, + 0.11622601002454758, + -0.05676949769258499, + 0.06581912934780121, + -0.11920367926359177 + ] + }, + { + "id": "/en/an_american_crime", + "initial_release_date": "2007-01-19", + "genre": [ + "Crime Fiction", + "Biographical film", + "Indie film", + "Drama" + ], + "directed_by": [ + "Tommy O'Haver" + ], + "name": "An American Crime", + "film_vector": [ + -0.3818797469139099, + -0.3194834887981415, + -0.265198290348053, + -0.15656395256519318, + 0.03640762344002724, + -0.2970435321331024, + -0.06629195809364319, + -0.2621594965457916, + 0.006271585822105408, + -0.2766970098018646 + ] + }, + { + "id": "/en/an_american_haunting", + "initial_release_date": "2005-11-05", + "genre": [ + "Horror", + "Mystery", + "Thriller" + ], + "directed_by": [ + "Courtney Solomon" + ], + "name": "An American Haunting", + "film_vector": [ + -0.24923893809318542, + -0.46490854024887085, + -0.10908554494380951, + 0.005601099692285061, + 0.19911587238311768, + -0.0424666665494442, + 0.1965274214744568, + 0.04342520982027054, + 0.1965586543083191, + -0.18486982583999634 + ] + }, + { + "id": "/en/an_american_tail_the_mystery_of_the_night_monster", + "initial_release_date": "2000-07-25", + "genre": [ + "Fantasy", + "Animated cartoon", + "Animation", + "Music", + "Family", + "Adventure Film", + "Children's Fantasy", + "Children's/Family", + "Family-Oriented Adventure" + ], + "directed_by": [ + "Larry Latham" + ], + "name": "An American Tail: The Mystery of the Night Monster", + "film_vector": [ + -0.062110673636198044, + -0.1675778031349182, + 0.06424807012081146, + 0.41540324687957764, + -0.14323949813842773, + 0.01672753319144249, + -0.06602101773023605, + 0.14644017815589905, + 0.10758160054683685, + -0.20245972275733948 + ] + }, + { + "id": "/en/an_evening_with_kevin_smith", + "genre": [ + "Documentary film", + "Stand-up comedy", + "Indie film", + "Film & Television History", + "Comedy", + "Biographical film", + "Media studies" + ], + "directed_by": [ + "J.M. Kenny" + ], + "name": "An Evening with Kevin Smith", + "film_vector": [ + -0.23560580611228943, + 0.03993409126996994, + -0.36823228001594543, + 0.0016501806676387787, + -0.30841201543807983, + -0.4097939729690552, + -0.010033432394266129, + -0.08529068529605865, + 0.14537502825260162, + -0.05154456943273544 + ] + }, + { + "id": "/en/an_evening_with_kevin_smith_2006", + "genre": [ + "Documentary film" + ], + "directed_by": [ + "J.M. Kenny" + ], + "name": "An Evening with Kevin Smith 2: Evening Harder", + "film_vector": [ + 0.07187023013830185, + -0.054346539080142975, + -0.1097550094127655, + -0.025393985211849213, + 0.096221424639225, + -0.3651759922504425, + 0.014563411474227905, + -0.12776169180870056, + 0.07347780466079712, + -0.0037305084988474846 + ] + }, + { + "id": "/en/an_everlasting_piece", + "initial_release_date": "2000-12-25", + "genre": [ + "Comedy" + ], + "directed_by": [ + "Barry Levinson" + ], + "name": "An Everlasting Piece", + "film_vector": [ + 0.14099442958831787, + 0.09090809524059296, + -0.22687870264053345, + 0.0057169971987605095, + 0.06279782205820084, + -0.12626123428344727, + 0.1913142204284668, + 0.11225735396146774, + -0.028212128207087517, + -0.20510396361351013 + ] + }, + { + "id": "/en/an_extremely_goofy_movie", + "initial_release_date": "2000-02-29", + "genre": [ + "Animation", + "Coming of age", + "Animated Musical", + "Children's/Family", + "Comedy" + ], + "directed_by": [ + "Ian Harrowell", + "Douglas McCarthy" + ], + "name": "An Extremely Goofy Movie", + "film_vector": [ + -0.04148397594690323, + 0.07845458388328552, + -0.3454483151435852, + 0.44535714387893677, + -0.15341034531593323, + -0.026829378679394722, + -0.042118608951568604, + -0.013756979256868362, + 0.20653778314590454, + -0.07167130708694458 + ] + }, + { + "id": "/en/an_inconvenient_truth", + "initial_release_date": "2006-01-24", + "genre": [ + "Documentary film" + ], + "directed_by": [ + "Davis Guggenheim" + ], + "name": "An Inconvenient Truth", + "film_vector": [ + 0.04770888388156891, + -0.09997296333312988, + 0.0923522561788559, + -0.09295150637626648, + -0.03015890158712864, + -0.3701690435409546, + -0.14008650183677673, + -0.016035348176956177, + 0.11510613560676575, + 0.02096896432340145 + ] + }, + { + "id": "/en/an_unfinished_life", + "initial_release_date": "2005-08-19", + "genre": [ + "Melodrama", + "Drama" + ], + "directed_by": [ + "Lasse Hallstr\u00f6m" + ], + "name": "An Unfinished Life", + "film_vector": [ + -0.09877994656562805, + -0.067314013838768, + -0.18582196533679962, + -0.2713407278060913, + 0.11535456776618958, + -0.033039554953575134, + -0.10515926778316498, + 0.05889516323804855, + 0.10090100765228271, + -0.1652832329273224 + ] + }, + { + "id": "/en/anacondas_the_hunt_for_the_blood_orchid", + "initial_release_date": "2004-08-25", + "genre": [ + "Thriller", + "Adventure Film", + "Horror", + "Action Film", + "Action/Adventure", + "Natural horror film", + "Jungle Film" + ], + "directed_by": [ + "Dwight H. Little" + ], + "name": "Anacondas: The Hunt for the Blood Orchid", + "film_vector": [ + -0.28035736083984375, + -0.1737029254436493, + 0.014246774837374687, + 0.19558775424957275, + 0.16175225377082825, + -0.18123766779899597, + 0.031238000839948654, + 0.19860239326953888, + -0.059993356466293335, + -0.10144822299480438 + ] + }, + { + "id": "/en/anal_pick-up", + "genre": [ + "Pornographic film", + "Gay pornography" + ], + "directed_by": [ + "Decklin" + ], + "name": "Anal Pick-Up", + "film_vector": [ + -0.1292879581451416, + 0.07243499159812927, + -0.2725068926811218, + 0.08787233382463455, + 0.010004128329455853, + -0.2152870148420334, + 0.07913380116224289, + -0.09284082055091858, + 0.19638624787330627, + -0.058705274015665054 + ] + }, + { + "id": "/en/analyze_that", + "initial_release_date": "2002-12-06", + "genre": [ + "Buddy film", + "Crime Comedy", + "Gangster Film", + "Comedy" + ], + "directed_by": [ + "Harold Ramis" + ], + "name": "Analyze That", + "film_vector": [ + -0.06286367028951645, + -0.1264679729938507, + -0.41632938385009766, + -0.019794201478362083, + 0.02246934361755848, + -0.2992013692855835, + 0.16444465517997742, + -0.15634582936763763, + -0.17826490104198456, + -0.19017377495765686 + ] + }, + { + "id": "/en/anamorph", + "genre": [ + "Psychological thriller", + "Crime Fiction", + "Thriller", + "Mystery", + "Crime Thriller", + "Suspense" + ], + "directed_by": [ + "H.S. Miller" + ], + "name": "Anamorph", + "film_vector": [ + -0.440166711807251, + -0.39558106660842896, + -0.1913137286901474, + -0.013938713818788528, + -0.021022429689764977, + 0.019391685724258423, + 0.10588859021663666, + 0.11510604619979858, + 0.025646887719631195, + -0.06603270769119263 + ] + }, + { + "id": "/en/anand_2004", + "initial_release_date": "2004-10-15", + "genre": [ + "Musical", + "Comedy", + "Drama", + "Musical comedy", + "Musical Drama", + "Tollywood", + "World cinema" + ], + "directed_by": [ + "Sekhar Kammula" + ], + "name": "Anand", + "film_vector": [ + -0.5310782194137573, + 0.425070583820343, + -0.1831214725971222, + -0.027345169335603714, + -0.13212046027183533, + -0.1678977906703949, + 0.10020443797111511, + 0.09354829788208008, + -0.019028838723897934, + 0.019210662692785263 + ] + }, + { + "id": "/en/anbe_aaruyire", + "initial_release_date": "2005-08-15", + "genre": [ + "Romance Film", + "Tamil cinema", + "World cinema", + "Drama" + ], + "directed_by": [ + "S. J. Surya" + ], + "name": "Anbe Aaruyire", + "film_vector": [ + -0.5251732468605042, + 0.41591066122055054, + -0.04863302782177925, + 0.0687759667634964, + 0.18253080546855927, + -0.055699530988931656, + 0.03006359562277794, + -0.0531422421336174, + 0.03506238013505936, + -0.1202462762594223 + ] + }, + { + "id": "/en/anbe_sivam", + "initial_release_date": "2003-01-14", + "genre": [ + "Musical", + "Musical comedy", + "Comedy", + "Adventure Film", + "Tamil cinema", + "World cinema", + "Drama", + "Musical Drama" + ], + "directed_by": [ + "Sundar C." + ], + "name": "Love is God", + "film_vector": [ + -0.45953288674354553, + 0.40540775656700134, + -0.30217909812927246, + 0.08442562818527222, + -0.02519950270652771, + -0.14790651202201843, + -0.006147567182779312, + 0.16809280216693878, + -0.02053956501185894, + -0.04086688905954361 + ] + }, + { + "id": "/en/ancanar", + "genre": [ + "Fantasy", + "Adventure Film", + "Action/Adventure" + ], + "directed_by": [ + "Sam R. Balcomb", + "Raiya Corsiglia" + ], + "name": "Ancanar", + "film_vector": [ + -0.27721622586250305, + 0.014983993954956532, + 0.004984775558114052, + 0.3060576617717743, + 0.14091843366622925, + -0.07419990003108978, + -0.16661176085472107, + -0.03198055922985077, + 0.03415995463728905, + -0.2889312505722046 + ] + }, + { + "id": "/en/anchorman_the_legend_of_ron_burgundy", + "initial_release_date": "2004-06-28", + "genre": [ + "Comedy" + ], + "directed_by": [ + "Adam McKay" + ], + "name": "Anchorman: The Legend of Ron Burgundy", + "film_vector": [ + 0.07169254869222641, + -0.12918037176132202, + -0.2804884910583496, + 0.19390004873275757, + -0.03649264574050903, + -0.2745344042778015, + 0.18087121844291687, + -0.1626390516757965, + -0.09716678410768509, + -0.04843180254101753 + ] + }, + { + "id": "/en/andaaz", + "initial_release_date": "2003-05-23", + "genre": [ + "Musical", + "Romance Film", + "Drama", + "Musical Drama" + ], + "directed_by": [ + "Raj Kanwar" + ], + "name": "Andaaz", + "film_vector": [ + -0.35386985540390015, + 0.2251960039138794, + -0.42742079496383667, + 0.014553559944033623, + -0.022472452372312546, + -0.06243884190917015, + -0.11145064979791641, + 0.08480160683393478, + 0.10059120506048203, + 0.005402153357863426 + ] + }, + { + "id": "/en/andarivaadu", + "initial_release_date": "2005-06-03", + "genre": [ + "Comedy" + ], + "directed_by": [ + "Srinu Vaitla" + ], + "name": "Andarivaadu", + "film_vector": [ + -0.0597887821495533, + 0.31344085931777954, + -0.11444079875946045, + 0.018577495589852333, + 0.09617358446121216, + -0.0873500406742096, + 0.367043137550354, + -0.02511308342218399, + -0.07179386168718338, + -0.07509717345237732 + ] + }, + { + "id": "/en/andhrawala", + "initial_release_date": "2004-01-01", + "genre": [ + "Adventure Film", + "Action Film", + "Tollywood", + "Drama" + ], + "directed_by": [ + "Puri Jagannadh", + "V.V.S. Ram" + ], + "name": "Andhrawala", + "film_vector": [ + -0.5242118239402771, + 0.3537300229072571, + 0.02378680370748043, + 0.18048472702503204, + 0.09206010401248932, + -0.11615575850009918, + 0.10548130422830582, + -0.107937291264534, + -0.11823669075965881, + -0.011412937194108963 + ] + }, + { + "id": "/en/ang_tanging_ina", + "initial_release_date": "2003-05-28", + "genre": [ + "Comedy", + "Drama" + ], + "directed_by": [ + "Wenn V. Deramas" + ], + "name": "Ang Tanging Ina", + "film_vector": [ + -0.18285450339317322, + 0.24999238550662994, + -0.2674749791622162, + -0.07371371239423752, + -0.014916817657649517, + 0.025798015296459198, + 0.12739387154579163, + -0.08399595320224762, + 0.03457355126738548, + -0.1954738199710846 + ] + }, + { + "id": "/en/angel_eyes", + "initial_release_date": "2001-05-18", + "genre": [ + "Romance Film", + "Crime Fiction", + "Drama" + ], + "directed_by": [ + "Luis Mandoki" + ], + "name": "Angel Eyes", + "film_vector": [ + -0.4156140685081482, + -0.13200505077838898, + -0.21458271145820618, + -0.03357645124197006, + 0.16858655214309692, + 0.0658421665430069, + -0.11671387404203415, + -0.09796245396137238, + 0.1689906269311905, + -0.26005518436431885 + ] + }, + { + "id": "/en/angel-a", + "initial_release_date": "2005-12-21", + "genre": [ + "Romance Film", + "Fantasy", + "Comedy", + "Romantic comedy", + "Drama" + ], + "directed_by": [ + "Luc Besson" + ], + "name": "Angel-A", + "film_vector": [ + -0.24069714546203613, + -0.017725259065628052, + -0.3139747381210327, + 0.13177356123924255, + 0.3337404727935791, + 0.022205442190170288, + -0.15435725450515747, + 0.05895897373557091, + 0.10453735291957855, + -0.17639893293380737 + ] + }, + { + "id": "/en/angels_and_demons_2008", + "initial_release_date": "2009-05-04", + "genre": [ + "Thriller", + "Mystery", + "Crime Fiction" + ], + "directed_by": [ + "Ron Howard" + ], + "name": "Angels & Demons", + "film_vector": [ + -0.4440920948982239, + -0.3592578172683716, + -0.196928471326828, + -0.09172385931015015, + -0.11608333885669708, + 0.1939632147550583, + 0.0421123281121254, + -0.02518499456346035, + 0.14082355797290802, + -0.21882334351539612 + ] + }, + { + "id": "/en/angels_and_virgins", + "initial_release_date": "2007-12-17", + "genre": [ + "Romance Film", + "Comedy", + "Adventure Film", + "Drama" + ], + "directed_by": [ + "David Leland" + ], + "name": "Virgin Territory", + "film_vector": [ + -0.3605750799179077, + 0.01776963286101818, + -0.2716206908226013, + 0.17697647213935852, + 0.1856917291879654, + -0.13689368963241577, + -0.07626952230930328, + -0.06633427739143372, + 0.14333736896514893, + -0.18688321113586426 + ] + }, + { + "id": "/en/angels_in_the_infield", + "initial_release_date": "2000-04-09", + "genre": [ + "Fantasy", + "Sports", + "Family", + "Children's/Family", + "Heavenly Comedy", + "Comedy" + ], + "directed_by": [ + "Robert King" + ], + "name": "Angels in the Infield", + "film_vector": [ + 0.04725056141614914, + 0.045512907207012177, + -0.2861102223396301, + 0.020108073949813843, + -0.2459632158279419, + 0.16158270835876465, + -0.06296882778406143, + -0.007531505078077316, + 0.08966080099344254, + -0.08674858510494232 + ] + }, + { + "id": "/en/anger_management_2003", + "initial_release_date": "2003-03-05", + "genre": [ + "Black comedy", + "Slapstick", + "Comedy" + ], + "directed_by": [ + "Peter Segal" + ], + "name": "Anger Management", + "film_vector": [ + -0.04140668362379074, + 0.0018581291660666466, + -0.41249367594718933, + -0.04679207503795624, + -0.19436201453208923, + -0.14591103792190552, + 0.26887813210487366, + -0.13627174496650696, + 0.013402648270130157, + -0.1287439465522766 + ] + }, + { + "id": "/en/angli_the_movie", + "initial_release_date": "2005-05-28", + "genre": [ + "Thriller", + "Action Film", + "Crime Fiction" + ], + "directed_by": [ + "Mario Busietta" + ], + "name": "Angli: The Movie", + "film_vector": [ + -0.4863036572933197, + 0.08301682025194168, + 0.003802293911576271, + -0.07249283790588379, + 0.09980858862400055, + -0.022697273641824722, + 0.05902102217078209, + -0.08221352100372314, + 0.036599043756723404, + -0.10503983497619629 + ] + }, + { + "id": "/en/animal_factory", + "initial_release_date": "2000-10-22", + "genre": [ + "Crime Fiction", + "Prison film", + "Drama" + ], + "directed_by": [ + "Steve Buscemi" + ], + "name": "Animal Factory", + "film_vector": [ + -0.189869686961174, + -0.1447194218635559, + 0.03012969344854355, + -0.09051337093114853, + -0.06694599241018295, + -0.17697083950042725, + 0.014518656767904758, + -0.10572846978902817, + 0.05681198835372925, + -0.27340394258499146 + ] + }, + { + "id": "/en/anjaneya", + "initial_release_date": "2003-10-24", + "genre": [ + "Romance Film", + "Crime Fiction", + "Drama", + "World cinema", + "Tamil cinema" + ], + "directed_by": [ + "Maharajan", + "N.Maharajan" + ], + "name": "Anjaneya", + "film_vector": [ + -0.6493126153945923, + 0.32442712783813477, + -0.04789796099066734, + 0.020510174334049225, + 0.05860326811671257, + -0.07491879165172577, + 0.07678082585334778, + -0.11214236915111542, + 0.030001170933246613, + -0.11825509369373322 + ] + }, + { + "id": "/en/ankahee", + "initial_release_date": "2006-05-19", + "genre": [ + "Romance Film", + "Thriller", + "Drama" + ], + "directed_by": [ + "Vikram Bhatt" + ], + "name": "Ankahee", + "film_vector": [ + -0.4558697044849396, + 0.10833586752414703, + -0.21213781833648682, + 0.10126990079879761, + 0.36342954635620117, + -0.002010045573115349, + 0.059271544218063354, + -0.10371103882789612, + 0.11457601189613342, + -0.08263974636793137 + ] + }, + { + "id": "/en/annapolis_2006", + "genre": [ + "Romance Film", + "Sports", + "Drama" + ], + "directed_by": [ + "Justin Lin" + ], + "name": "Annapolis", + "film_vector": [ + -0.15256446599960327, + -0.008032646030187607, + -0.2628743052482605, + -0.048812415450811386, + 0.013296224176883698, + 0.03840752691030502, + -0.27343636751174927, + -0.22980567812919617, + 0.04087706282734871, + -0.2074567824602127 + ] + }, + { + "id": "/en/annavaram_2007", + "initial_release_date": "2006-12-29", + "genre": [ + "Thriller", + "Musical", + "Action Film", + "Romance Film", + "Tollywood", + "World cinema" + ], + "directed_by": [ + "Gridhar", + "Bhimaneni Srinivasa Rao", + "Sippy" + ], + "name": "Annavaram", + "film_vector": [ + -0.6851447820663452, + 0.25590652227401733, + -0.11437998712062836, + 0.08495157957077026, + 0.1360139548778534, + -0.1295955628156662, + 0.06783458590507507, + -0.07950802147388458, + 0.0558854341506958, + 0.00916086696088314 + ] + }, + { + "id": "/en/anniyan", + "initial_release_date": "2005-06-10", + "genre": [ + "Horror", + "Short Film", + "Psychological thriller", + "Thriller", + "Musical Drama", + "Action Film", + "Drama" + ], + "directed_by": [ + "S. Shankar" + ], + "name": "Anniyan", + "film_vector": [ + -0.6064292192459106, + -0.008693082258105278, + -0.1664201021194458, + 0.035952210426330566, + 0.04206737130880356, + -0.1704312115907669, + 0.12837038934230804, + 0.04217816889286041, + 0.16454976797103882, + -0.025129348039627075 + ] + }, + { + "id": "/en/another_gay_movie", + "initial_release_date": "2006-04-28", + "genre": [ + "Parody", + "Coming of age", + "LGBT", + "Gay Themed", + "Romantic comedy", + "Romance Film", + "Gay", + "Gay Interest", + "Sex comedy", + "Comedy", + "Pornographic film" + ], + "directed_by": [ + "Todd Stephens" + ], + "name": "Another Gay Movie", + "film_vector": [ + -0.14389359951019287, + 0.07914774864912033, + -0.5045472383499146, + 0.11197496950626373, + -0.09796974062919617, + -0.19963620603084564, + -0.042794860899448395, + 0.15466031432151794, + 0.0090895164757967, + -0.006058163940906525 + ] + }, + { + "id": "/en/ant_man", + "initial_release_date": "2015-07-17", + "genre": [ + "Thriller", + "Science Fiction", + "Action/Adventure", + "Superhero movie", + "Comedy" + ], + "directed_by": [ + "Peyton Reed" + ], + "name": "Ant-Man", + "film_vector": [ + -0.44029033184051514, + -0.14508900046348572, + -0.30993589758872986, + 0.27537450194358826, + -0.19960089027881622, + -0.025340048596262932, + -0.02303551696240902, + -0.1792857050895691, + -0.09430290013551712, + -0.03368902578949928 + ] + }, + { + "id": "/en/anthony_zimmer", + "initial_release_date": "2005-04-27", + "genre": [ + "Thriller", + "Romance Film", + "World cinema", + "Crime Thriller" + ], + "directed_by": [ + "J\u00e9r\u00f4me Salle" + ], + "name": "Anthony Zimmer", + "film_vector": [ + -0.489185631275177, + -0.1507003754377365, + -0.18640638887882233, + -0.037955738604068756, + 0.16426917910575867, + -0.1855740249156952, + -0.0037812618538737297, + -0.13771086931228638, + 0.11070667207241058, + -0.18175899982452393 + ] + }, + { + "id": "/en/antwone_fisher_2003", + "initial_release_date": "2002-09-12", + "genre": [ + "Romance Film", + "Biographical film", + "Drama" + ], + "directed_by": [ + "Denzel Washington" + ], + "name": "Antwone Fisher", + "film_vector": [ + -0.27933287620544434, + 0.01597728207707405, + -0.24223335087299347, + 0.10700607299804688, + 0.24006441235542297, + -0.2230602353811264, + -0.1519487202167511, + -0.09998913109302521, + 0.07546088099479675, + -0.20986658334732056 + ] + }, + { + "id": "/en/anukokunda_oka_roju", + "initial_release_date": "2005-06-30", + "genre": [ + "Thriller", + "Horror", + "Tollywood", + "World cinema" + ], + "directed_by": [ + "Chandra Sekhar Yeleti" + ], + "name": "Anukokunda Oka Roju", + "film_vector": [ + -0.5025879144668579, + -0.0009006280452013016, + 0.01724979281425476, + 0.10779300332069397, + 0.15553715825080872, + -0.08105277270078659, + 0.20276522636413574, + -0.07613007724285126, + 0.14652203023433685, + -0.1623978316783905 + ] + }, + { + "id": "/en/anus_magillicutty", + "initial_release_date": "2003-04-15", + "genre": [ + "B movie", + "Romance Film", + "Comedy" + ], + "directed_by": [ + "Morey Fineburgh" + ], + "name": "Anus Magillicutty", + "film_vector": [ + -0.3876708745956421, + 0.138946533203125, + -0.36623644828796387, + 0.16814696788787842, + 0.10925936698913574, + -0.13488049805164337, + 0.07633757591247559, + -0.1480773389339447, + 0.06065690517425537, + -0.12631621956825256 + ] + }, + { + "id": "/en/any_way_the_wind_blows", + "initial_release_date": "2003-05-17", + "genre": [ + "Comedy-drama" + ], + "directed_by": [ + "Tom Barman" + ], + "name": "Any Way the Wind Blows", + "film_vector": [ + 0.008339963853359222, + 0.009571284055709839, + -0.2755695581436157, + -0.12628760933876038, + 0.04078216105699539, + -0.009406449273228645, + -0.003309108316898346, + -0.032645151019096375, + -0.020039090886712074, + -0.19594347476959229 + ] + }, + { + "id": "/en/anything_else", + "initial_release_date": "2003-08-27", + "genre": [ + "Romantic comedy", + "Romance Film", + "Comedy" + ], + "directed_by": [ + "Woody Allen" + ], + "name": "Anything Else", + "film_vector": [ + -0.3379748463630676, + 0.10682555288076401, + -0.48536837100982666, + 0.15282270312309265, + 0.2214895784854889, + -0.04513724148273468, + -0.012102187611162663, + -0.15466177463531494, + 0.1586533635854721, + -0.2166387438774109 + ] + }, + { + "id": "/en/apasionados", + "initial_release_date": "2002-06-06", + "genre": [ + "Romantic comedy", + "Romance Film", + "World cinema", + "Comedy", + "Drama" + ], + "directed_by": [ + "Juan Jos\u00e9 Jusid" + ], + "name": "Apasionados", + "film_vector": [ + -0.4436575770378113, + 0.27434098720550537, + -0.3500620126724243, + 0.018412996083498, + 0.065566286444664, + -0.08510074019432068, + -0.00865144282579422, + 0.03725995868444443, + 0.16313540935516357, + -0.21213841438293457 + ] + }, + { + "id": "/en/apocalypto", + "initial_release_date": "2006-12-08", + "genre": [ + "Action Film", + "Adventure Film", + "Epic film", + "Thriller", + "Drama" + ], + "directed_by": [ + "Mel Gibson" + ], + "name": "Apocalypto", + "film_vector": [ + -0.5541702508926392, + 0.005952438339591026, + -0.1331290900707245, + 0.1927107274532318, + 0.029773201793432236, + -0.17530962824821472, + -0.07791655510663986, + -0.05471121892333031, + -0.03366681933403015, + -0.05060608685016632 + ] + }, + { + "id": "/en/aprils_shower", + "initial_release_date": "2006-01-13", + "genre": [ + "Romantic comedy", + "Indie film", + "Romance Film", + "LGBT", + "Gay", + "Gay Interest", + "Gay Themed", + "Sex comedy", + "Comedy", + "Drama" + ], + "directed_by": [ + "Trish Doolan" + ], + "name": "April's Shower", + "film_vector": [ + -0.22147716581821442, + 0.04250142350792885, + -0.5805555582046509, + 0.08195574581623077, + -0.036423929035663605, + -0.1219698116183281, + -0.08668072521686554, + 0.187529519200325, + 0.04825173318386078, + 0.004523022100329399 + ] + }, + { + "id": "/en/aquamarine_2006", + "initial_release_date": "2006-02-26", + "genre": [ + "Coming of age", + "Teen film", + "Romance Film", + "Family", + "Fantasy", + "Fantasy Comedy", + "Comedy" + ], + "directed_by": [ + "Elizabeth Allen Rosenbaum" + ], + "name": "Aquamarine", + "film_vector": [ + -0.3651082515716553, + 0.009190283715724945, + -0.3549656867980957, + 0.3046751022338867, + -0.03892369940876961, + 0.0304866936057806, + -0.16680626571178436, + -0.03673963621258736, + 0.15169969201087952, + -0.11081992834806442 + ] + }, + { + "id": "/en/arabian_nights", + "initial_release_date": "2000-04-30", + "genre": [ + "Family", + "Fantasy", + "Adventure Film" + ], + "directed_by": [ + "Steve Barron" + ], + "name": "Arabian Nights", + "film_vector": [ + -0.15382739901542664, + 0.10114426910877228, + 0.04073280841112137, + 0.22806555032730103, + 0.2506129741668701, + -0.026630938053131104, + -0.14195409417152405, + 0.04709619656205177, + 0.006313635036349297, + -0.3123563528060913 + ] + }, + { + "id": "/en/aragami", + "initial_release_date": "2003-03-27", + "genre": [ + "Thriller", + "Action/Adventure", + "World cinema", + "Japanese Movies", + "Action Film", + "Drama" + ], + "directed_by": [ + "Ryuhei Kitamura" + ], + "name": "Aragami", + "film_vector": [ + -0.5013219714164734, + -0.01620086096227169, + -0.012606645002961159, + 0.19683754444122314, + 0.10338383913040161, + -0.013548661023378372, + -0.0015271743759512901, + 0.008945594541728497, + 0.08029839396476746, + -0.13971483707427979 + ] + }, + { + "id": "/en/arahan", + "initial_release_date": "2004-04-30", + "genre": [ + "Action Film", + "Comedy", + "Korean drama", + "East Asian cinema", + "World cinema" + ], + "directed_by": [ + "Ryoo Seung-wan" + ], + "name": "Arahan", + "film_vector": [ + -0.5210731029510498, + 0.2825250029563904, + -0.09107375144958496, + 0.11768417805433273, + -0.09937092661857605, + -0.14329224824905396, + 0.06514710187911987, + -0.06250281631946564, + 0.0699710100889206, + -0.1598162055015564 + ] + }, + { + "id": "/en/ararat", + "initial_release_date": "2002-05-20", + "genre": [ + "LGBT", + "Political drama", + "War film", + "Drama" + ], + "directed_by": [ + "Atom Egoyan" + ], + "name": "Ararat", + "film_vector": [ + -0.27235135436058044, + 0.274906188249588, + -0.041966021060943604, + -0.14459934830665588, + -0.0687122717499733, + -0.07396703958511353, + -0.09752675145864487, + 0.03610480949282646, + 0.19087420403957367, + -0.19855010509490967 + ] + }, + { + "id": "/en/are_we_there_yet", + "initial_release_date": "2005-01-21", + "genre": [ + "Family", + "Adventure Film", + "Romance Film", + "Comedy", + "Drama" + ], + "directed_by": [ + "Brian Levant" + ], + "name": "Are We There Yet", + "film_vector": [ + -0.4651140570640564, + 0.11930437386035919, + -0.2870033383369446, + 0.2091452181339264, + -0.1682138592004776, + -0.059562936425209045, + -0.08950482308864594, + -0.12603940069675446, + 0.10004322230815887, + -0.005561015568673611 + ] + }, + { + "id": "/en/arinthum_ariyamalum", + "initial_release_date": "2005-05-20", + "genre": [ + "Crime Fiction", + "Family", + "Romance Film", + "Comedy", + "Tamil cinema", + "World cinema", + "Drama" + ], + "directed_by": [ + "Vishnuvardhan" + ], + "name": "Arinthum Ariyamalum", + "film_vector": [ + -0.5523391366004944, + 0.2944381535053253, + -0.00593169778585434, + 0.015327896922826767, + 0.020036663860082626, + -0.03709357976913452, + 0.07867012917995453, + -0.09383605420589447, + -0.028260447084903717, + -0.2514665424823761 + ] + }, + { + "id": "/en/arisan", + "initial_release_date": "2003-12-10", + "genre": [ + "Comedy", + "Drama" + ], + "directed_by": [ + "Nia Dinata" + ], + "name": "Arisan!", + "film_vector": [ + -0.18575173616409302, + 0.24508818984031677, + -0.22679764032363892, + 0.0005282517522573471, + -0.02779141440987587, + 0.1156383529305458, + 0.08378773182630539, + -0.15080535411834717, + 0.05560476332902908, + -0.20646551251411438 + ] + }, + { + "id": "/en/arjun_2004", + "initial_release_date": "2004-08-18", + "genre": [ + "Action Film", + "Tollywood", + "World cinema" + ], + "directed_by": [ + "Gunasekhar", + "J. Hemambar" + ], + "name": "Arjun", + "film_vector": [ + -0.4508360028266907, + 0.31886839866638184, + 0.07489574700593948, + 0.03838089108467102, + 0.12062197923660278, + -0.13156557083129883, + 0.13440336287021637, + -0.22010323405265808, + -0.17861080169677734, + -0.006893469020724297 + ] + }, + { + "id": "/en/armaan", + "initial_release_date": "2003-05-16", + "genre": [ + "Romance Film", + "Family", + "Drama" + ], + "directed_by": [ + "Honey Irani" + ], + "name": "Armaan", + "film_vector": [ + -0.31613820791244507, + 0.16803541779518127, + -0.23884522914886475, + 0.13477474451065063, + 0.3855525851249695, + -0.003034265711903572, + -0.07841405272483826, + -0.13837818801403046, + 0.04175694286823273, + -0.14627455174922943 + ] + }, + { + "id": "/en/around_the_bend", + "initial_release_date": "2004-10-08", + "genre": [ + "Family Drama", + "Comedy-drama", + "Road movie", + "Drama" + ], + "directed_by": [ + "Jordan Roberts" + ], + "name": "Around the Bend", + "film_vector": [ + -0.1750609278678894, + 0.011882727965712547, + -0.4304097592830658, + 0.005098890513181686, + -0.18634313344955444, + -0.04699074476957321, + -0.13266783952713013, + -0.18036669492721558, + 0.1022980734705925, + -0.06367718428373337 + ] + }, + { + "id": "/en/around_the_world_in_80_days_2004", + "initial_release_date": "2004-06-13", + "genre": [ + "Adventure Film", + "Action Film", + "Family", + "Western", + "Romance Film", + "Comedy" + ], + "directed_by": [ + "Frank Coraci" + ], + "name": "Around the World in 80 Days", + "film_vector": [ + -0.399733304977417, + 0.12071133404970169, + -0.06804437935352325, + 0.29033732414245605, + -0.013728651218116283, + -0.27789679169654846, + -0.10754302144050598, + -0.09548217058181763, + -0.06511116027832031, + -0.13594256341457367 + ] + }, + { + "id": "/en/art_of_the_devil_2", + "initial_release_date": "2005-12-01", + "genre": [ + "Horror", + "Slasher", + "Fantasy", + "Mystery" + ], + "directed_by": [ + "Pasith Buranajan", + "Seree Phongnithi", + "Yosapong Polsap", + "Putipong Saisikaew", + "Art Thamthrakul", + "Kongkiat Khomsiri", + "Isara Nadee" + ], + "name": "Art of the Devil 2", + "film_vector": [ + -0.399852991104126, + -0.3390026092529297, + 0.00806966982781887, + 0.08988703042268753, + -0.03787490725517273, + 0.07207099348306656, + 0.17157965898513794, + 0.12934812903404236, + 0.10864819586277008, + -0.15850451588630676 + ] + }, + { + "id": "/en/art_school_confidential", + "genre": [ + "Comedy-drama" + ], + "directed_by": [ + "Terry Zwigoff" + ], + "name": "Art School Confidential", + "film_vector": [ + 0.03134152665734291, + 0.04597022384405136, + -0.3526610732078552, + -0.21372637152671814, + 0.04154307395219803, + -0.035928383469581604, + 0.11980713158845901, + -0.01045962329953909, + 0.12372469156980515, + -0.24502624571323395 + ] + }, + { + "id": "/en/arul", + "initial_release_date": "2004-05-01", + "genre": [ + "Musical", + "Action Film", + "Tamil cinema", + "World cinema", + "Drama", + "Musical Drama" + ], + "directed_by": [ + "Hari" + ], + "name": "Arul", + "film_vector": [ + -0.5806245803833008, + 0.4183100759983063, + -0.1093984916806221, + 0.038850512355566025, + -0.04995085299015045, + -0.15526160597801208, + 0.0017913198098540306, + 0.07501327246427536, + 0.02889476902782917, + -0.023275304585695267 + ] + }, + { + "id": "/en/arya_2007", + "initial_release_date": "2007-08-10", + "genre": [ + "Romance Film", + "Drama", + "Tamil cinema", + "World cinema" + ], + "directed_by": [ + "Balasekaran" + ], + "name": "Aarya", + "film_vector": [ + -0.6027930378913879, + 0.4436737596988678, + -0.06034780293703079, + 0.042704857885837555, + 0.10804193466901779, + -0.05424384027719498, + 0.07514643669128418, + -0.11012235283851624, + 0.05021673068404198, + -0.07334025949239731 + ] + }, + { + "id": "/en/arya_2004", + "initial_release_date": "2004-05-07", + "genre": [ + "Musical", + "Romance Film", + "Romantic comedy", + "Musical comedy", + "Comedy", + "Drama", + "Musical Drama", + "World cinema", + "Tollywood" + ], + "directed_by": [ + "Sukumar" + ], + "name": "Arya", + "film_vector": [ + -0.46840888261795044, + 0.23802195489406586, + -0.2995007336139679, + 0.02147998847067356, + 0.03639768809080124, + -0.07713283598423004, + -0.07099515944719315, + 0.24502666294574738, + 0.035120002925395966, + -0.034031663089990616 + ] + }, + { + "id": "/en/aryan_2006", + "initial_release_date": "2006-12-05", + "genre": [ + "Action Film", + "Drama" + ], + "directed_by": [ + "Abhishek Kapoor" + ], + "name": "Aryan: Unbreakable", + "film_vector": [ + -0.24932831525802612, + 0.144019216299057, + 0.050539322197437286, + -0.06176076456904411, + 0.18049728870391846, + -0.19951550662517548, + 0.059828273952007294, + -0.12054018676280975, + -0.13614144921302795, + -0.07917870581150055 + ] + }, + { + "id": "/en/as_it_is_in_heaven", + "initial_release_date": "2004-08-20", + "genre": [ + "Musical", + "Comedy", + "Romance Film", + "Drama", + "Musical comedy", + "Musical Drama", + "World cinema" + ], + "directed_by": [ + "Kay Pollak" + ], + "name": "As It Is in Heaven", + "film_vector": [ + -0.3317238390445709, + 0.25304552912712097, + -0.40611493587493896, + -0.0068064406514167786, + -0.12338399887084961, + -0.05408806353807449, + -0.0663960799574852, + 0.21276284754276276, + 0.08168492466211319, + -0.03759736567735672 + ] + }, + { + "id": "/en/ashok", + "initial_release_date": "2006-07-13", + "genre": [ + "Action Film", + "Romance Film", + "Drama", + "Tollywood", + "World cinema" + ], + "directed_by": [ + "Surender Reddy" + ], + "name": "Ashok", + "film_vector": [ + -0.6679084300994873, + 0.36060458421707153, + -0.03275398164987564, + 0.03664346784353256, + 0.021654363721609116, + -0.17712241411209106, + 0.09649033099412918, + -0.09566488862037659, + -0.02939784526824951, + -0.02227146551012993 + ] + }, + { + "id": "/en/ask_the_dust_2006", + "initial_release_date": "2006-02-02", + "genre": [ + "Historical period drama", + "Film adaptation", + "Romance Film", + "Drama" + ], + "directed_by": [ + "Robert Towne" + ], + "name": "Ask the Dust", + "film_vector": [ + -0.39839455485343933, + 0.16083218157291412, + -0.18984898924827576, + -0.041393328458070755, + 0.08284921944141388, + -0.14558684825897217, + -0.11783343553543091, + 0.11127462983131409, + -0.014480888843536377, + -0.2629256248474121 + ] + }, + { + "id": "/en/asoka", + "initial_release_date": "2001-09-13", + "genre": [ + "Action Film", + "Romance Film", + "War film", + "Epic film", + "Musical", + "Bollywood", + "World cinema", + "Drama", + "Musical Drama" + ], + "directed_by": [ + "Santosh Sivan" + ], + "name": "Ashoka the Great", + "film_vector": [ + -0.4829058051109314, + 0.3119867742061615, + 0.0051110368221998215, + 0.031035292893648148, + 0.07948940992355347, + -0.24704419076442719, + 0.004343932960182428, + 0.10620000213384628, + -0.13693955540657043, + -0.07753510773181915 + ] + }, + { + "id": "/en/assault_on_precinct_13_2005", + "initial_release_date": "2005-01-19", + "genre": [ + "Thriller", + "Action Film", + "Remake", + "Crime Fiction", + "Drama" + ], + "directed_by": [ + "Jean-Fran\u00e7ois Richet" + ], + "name": "Assault on Precinct 13", + "film_vector": [ + -0.37469273805618286, + -0.3570220470428467, + -0.29934918880462646, + -0.019213860854506493, + 0.09824179112911224, + -0.16044116020202637, + -0.031803157180547714, + -0.20207761228084564, + -0.03529062494635582, + -0.06865349411964417 + ] + }, + { + "id": "/en/astitva", + "initial_release_date": "2000-10-06", + "genre": [ + "Art film", + "Bollywood", + "World cinema", + "Drama" + ], + "directed_by": [ + "Mahesh Manjrekar" + ], + "name": "Astitva", + "film_vector": [ + -0.5835236310958862, + 0.4068262279033661, + -0.0008003637194633484, + -0.012151408940553665, + -0.08551368862390518, + -0.15269386768341064, + 0.13224700093269348, + -0.08889982849359512, + 0.1093021035194397, + -0.08072131127119064 + ] + }, + { + "id": "/en/asylum_2005", + "initial_release_date": "2005-08-12", + "genre": [ + "Film adaptation", + "Romance Film", + "Thriller", + "Drama" + ], + "directed_by": [ + "David Mackenzie" + ], + "name": "Asylum", + "film_vector": [ + -0.34885358810424805, + -0.19522923231124878, + -0.2134246826171875, + -0.044540636241436005, + 0.23077353835105896, + -0.17015115916728973, + 0.05095795542001724, + 0.06581525504589081, + 0.10267112404108047, + -0.10557771474123001 + ] + }, + { + "id": "/en/atanarjuat", + "initial_release_date": "2001-05-13", + "genre": [ + "Fantasy", + "Drama" + ], + "directed_by": [ + "Zacharias Kunuk" + ], + "name": "Atanarjuat: The Fast Runner", + "film_vector": [ + -0.12063577771186829, + 0.1411949098110199, + 0.17571422457695007, + -0.0049829911440610886, + 0.027704443782567978, + 0.04964331537485123, + -0.12730997800827026, + 0.05993029475212097, + -0.15793798863887787, + -0.17662978172302246 + ] + }, + { + "id": "/en/athadu", + "initial_release_date": "2005-08-10", + "genre": [ + "Action Film", + "Thriller", + "Musical", + "Romance Film", + "Tollywood", + "World cinema" + ], + "directed_by": [ + "Trivikram Srinivas" + ], + "name": "Athadu", + "film_vector": [ + -0.6634848713874817, + 0.23847846686840057, + -0.09327666461467743, + 0.09254280477762222, + 0.05629080533981323, + -0.15667873620986938, + 0.08887222409248352, + -0.09579209983348846, + 0.05369479954242706, + -0.021656079217791557 + ] + }, + { + "id": "/en/atl_2006", + "initial_release_date": "2006-03-28", + "genre": [ + "Coming of age", + "Comedy", + "Drama" + ], + "directed_by": [ + "Chris Robinson" + ], + "name": "ATL", + "film_vector": [ + -0.2042018324136734, + 0.160475492477417, + -0.3326405882835388, + -0.08637742698192596, + -0.23637083172798157, + 0.09266722202301025, + -0.005517173558473587, + -0.15165477991104126, + 0.23719653487205505, + -0.043570034205913544 + ] + }, + { + "id": "/en/atlantis_the_lost_empire", + "initial_release_date": "2001-06-03", + "genre": [ + "Adventure Film", + "Science Fiction", + "Family", + "Animation" + ], + "directed_by": [ + "Gary Trousdale", + "Kirk Wise" + ], + "name": "Atlantis: The Lost Empire", + "film_vector": [ + -0.10183164477348328, + -0.0070024169981479645, + 0.07452187687158585, + 0.34743571281433105, + -0.03894423693418503, + -0.05869138240814209, + -0.1819758266210556, + 0.002472834661602974, + 0.008274243213236332, + -0.20958393812179565 + ] + }, + { + "id": "/en/atonement_2007", + "initial_release_date": "2007-08-28", + "genre": [ + "Romance Film", + "War film", + "Mystery", + "Drama", + "Music" + ], + "directed_by": [ + "Joe Wright" + ], + "name": "Atonement", + "film_vector": [ + -0.49134400486946106, + -0.02350890077650547, + -0.22729375958442688, + 0.021524548530578613, + 0.10478580743074417, + -0.14058032631874084, + -0.1813952475786209, + 0.03591436892747879, + 0.003670528531074524, + -0.2415427714586258 + ] + }, + { + "id": "/en/attagasam", + "initial_release_date": "2004-11-12", + "genre": [ + "Action Film", + "Thriller", + "Tamil cinema", + "World cinema", + "Drama" + ], + "directed_by": [ + "Saran" + ], + "name": "Attahasam", + "film_vector": [ + -0.6076648235321045, + 0.23317348957061768, + 0.018676310777664185, + 0.03564288094639778, + 0.06462382525205612, + -0.1476416289806366, + 0.10254596173763275, + -0.05448080599308014, + -0.025153838098049164, + -0.04557002708315849 + ] + }, + { + "id": "/en/attila_2001", + "genre": [ + "Adventure Film", + "History", + "Action Film", + "War film", + "Historical fiction", + "Biographical film" + ], + "directed_by": [ + "Dick Lowry" + ], + "name": "Attila", + "film_vector": [ + -0.3769395649433136, + 0.07657265663146973, + 0.10981053858995438, + 0.056307729333639145, + 0.0048776534385979176, + -0.28333526849746704, + -0.1692468225955963, + 0.09353601932525635, + -0.07144267112016678, + -0.2553260028362274 + ] + }, + { + "id": "/en/austin_powers_goldmember", + "initial_release_date": "2002-07-22", + "genre": [ + "Action Film", + "Crime Fiction", + "Comedy" + ], + "directed_by": [ + "Jay Roach" + ], + "name": "Austin Powers: Goldmember", + "film_vector": [ + -0.20091170072555542, + -0.19251519441604614, + -0.24969607591629028, + 0.11260093748569489, + 0.009167395532131195, + -0.15618577599525452, + 0.05036860704421997, + -0.32243984937667847, + -0.20895572006702423, + -0.1759602576494217 + ] + }, + { + "id": "/en/australian_rules", + "genre": [ + "Drama" + ], + "directed_by": [ + "Paul Goldman" + ], + "name": "Australian Rules", + "film_vector": [ + 0.1356058120727539, + 0.06630014628171921, + -0.12893061339855194, + -0.2781410217285156, + 0.015789953991770744, + 0.17653876543045044, + -0.10335332155227661, + -0.10669022798538208, + -0.03618998825550079, + 0.051351241767406464 + ] + }, + { + "id": "/en/auto", + "initial_release_date": "2007-02-16", + "genre": [ + "Action Film", + "Comedy", + "Tamil cinema", + "World cinema", + "Drama" + ], + "directed_by": [ + "Pushkar", + "Gayatri" + ], + "name": "Oram Po", + "film_vector": [ + -0.5639143586158752, + 0.3699287474155426, + -0.03592407703399658, + 0.022896302863955498, + -0.009749853983521461, + -0.12638495862483978, + 0.1193232387304306, + -0.1006431132555008, + -0.002830490469932556, + -0.07496272772550583 + ] + }, + { + "id": "/en/auto_focus", + "initial_release_date": "2002-09-08", + "genre": [ + "Biographical film", + "Indie film", + "Crime Fiction", + "Drama" + ], + "directed_by": [ + "Paul Schrader", + "Larry Karaszewski" + ], + "name": "Auto Focus", + "film_vector": [ + -0.5243303775787354, + -0.09084616601467133, + -0.22899222373962402, + -0.07585050910711288, + -0.07310143113136292, + -0.27766284346580505, + -0.09505908191204071, + -0.2340579777956009, + 0.2057991921901703, + -0.1965269148349762 + ] + }, + { + "id": "/en/autograph_2004", + "initial_release_date": "2004-02-14", + "genre": [ + "Musical", + "Romance Film", + "Drama", + "Musical Drama", + "Tamil cinema", + "World cinema" + ], + "directed_by": [ + "Cheran" + ], + "name": "Autograph", + "film_vector": [ + -0.5514554381370544, + 0.40998363494873047, + -0.1789582371711731, + -0.01756913587450981, + -0.07354708015918732, + -0.1848432868719101, + -0.030466191470623016, + -0.00965285673737526, + 0.0601835772395134, + -0.06891355663537979 + ] + }, + { + "id": "/en/avalon_2001", + "initial_release_date": "2001-01-20", + "genre": [ + "Science Fiction", + "Thriller", + "Action Film", + "Adventure Film", + "Fantasy", + "Drama" + ], + "directed_by": [ + "Mamoru Oshii" + ], + "name": "Avalon", + "film_vector": [ + -0.529358446598053, + -0.11366622149944305, + -0.11966574937105179, + 0.14834383130073547, + -0.0657745748758316, + 0.03877218812704086, + -0.17882071435451508, + -0.08982953429222107, + 0.14710089564323425, + -0.21224066615104675 + ] + }, + { + "id": "/en/avatar_2009", + "initial_release_date": "2009-12-10", + "genre": [ + "Science Fiction", + "Adventure Film", + "Fantasy", + "Action Film" + ], + "directed_by": [ + "James Cameron" + ], + "name": "Avatar", + "film_vector": [ + -0.3912856876850128, + 0.0012109223753213882, + 0.044774800539016724, + 0.3943019509315491, + -0.010671727359294891, + -0.055712006986141205, + -0.1905762106180191, + -0.06701105833053589, + 0.044917792081832886, + -0.0974033996462822 + ] + }, + { + "id": "/en/avenging_angelo", + "initial_release_date": "2002-08-30", + "genre": [ + "Action Film", + "Romance Film", + "Crime Fiction", + "Action/Adventure", + "Thriller", + "Romantic comedy", + "Crime Comedy", + "Gangster Film", + "Comedy" + ], + "directed_by": [ + "Martyn Burke" + ], + "name": "Avenging Angelo", + "film_vector": [ + -0.44914865493774414, + -0.17086338996887207, + -0.34374597668647766, + -0.0024903863668441772, + 0.053710002452135086, + -0.1879696100950241, + -0.12445248663425446, + -0.008786411955952644, + -0.09919355064630508, + -0.15764950215816498 + ] + }, + { + "id": "/en/awake_2007", + "initial_release_date": "2007-11-30", + "genre": [ + "Thriller", + "Crime Fiction", + "Mystery" + ], + "directed_by": [ + "Joby Harold" + ], + "name": "Awake", + "film_vector": [ + -0.48527204990386963, + -0.4157452881336212, + -0.14090028405189514, + -0.13922052085399628, + -0.01046367920935154, + 0.07997579872608185, + 0.03509967774152756, + -0.027547812089323997, + 0.11443914473056793, + -0.1475057303905487 + ] + }, + { + "id": "/en/awara_paagal_deewana", + "initial_release_date": "2002-06-20", + "genre": [ + "Action Film", + "World cinema", + "Musical", + "Crime Fiction", + "Musical comedy", + "Comedy", + "Bollywood", + "Drama", + "Musical Drama" + ], + "directed_by": [ + "Vikram Bhatt" + ], + "name": "Awara Paagal Deewana", + "film_vector": [ + -0.45474034547805786, + 0.3785404860973358, + -0.13878241181373596, + 0.03824511915445328, + 0.031327854841947556, + -0.11246149241924286, + 0.11133666336536407, + 0.05477278307080269, + -0.06072331592440605, + -0.05013778433203697 + ] + }, + { + "id": "/en/awesome_i_fuckin_shot_that", + "initial_release_date": "2006-01-06", + "genre": [ + "Concert film", + "Rockumentary", + "Hip hop film", + "Documentary film", + "Indie film" + ], + "directed_by": [ + "Adam Yauch" + ], + "name": "Awesome; I Fuckin' Shot That!", + "film_vector": [ + -0.28470203280448914, + -0.0044509172439575195, + -0.2118566632270813, + 0.08100096136331558, + -0.17981240153312683, + -0.4728885293006897, + -0.05346336588263512, + -0.05950603634119034, + 0.2224159687757492, + 0.09682212024927139 + ] + }, + { + "id": "/en/azumi", + "initial_release_date": "2003-05-10", + "genre": [ + "Action Film", + "Epic film", + "Adventure Film", + "Fantasy", + "Thriller" + ], + "directed_by": [ + "Ryuhei Kitamura" + ], + "name": "Azumi", + "film_vector": [ + -0.5649582147598267, + 0.052445702254772186, + -0.04262746125459671, + 0.22636395692825317, + 0.10401543229818344, + -0.07215303182601929, + -0.09002947807312012, + -0.04620395600795746, + 0.03386414796113968, + -0.13006077706813812 + ] + }, + { + "id": "/wikipedia/en_title/$00C6on_Flux_$0028film$0029", + "initial_release_date": "2005-12-01", + "genre": [ + "Science Fiction", + "Dystopia", + "Action Film", + "Thriller", + "Adventure Film" + ], + "directed_by": [ + "Karyn Kusama" + ], + "name": "\u00c6on Flux", + "film_vector": [ + -0.42930471897125244, + -0.1622050255537033, + -0.007030569016933441, + 0.1149166077375412, + 0.0412760004401207, + -0.07266155630350113, + -0.1575414389371872, + -0.0008047722512856126, + 0.10677583515644073, + -0.07892082631587982 + ] + }, + { + "id": "/en/baabul", + "initial_release_date": "2006-12-08", + "genre": [ + "Musical", + "Family", + "Romance Film", + "Bollywood", + "World cinema", + "Drama", + "Musical Drama" + ], + "directed_by": [ + "Ravi Chopra" + ], + "name": "Baabul", + "film_vector": [ + -0.5448785424232483, + 0.3780006170272827, + -0.2111089527606964, + 0.05144880712032318, + -0.06560524553060532, + -0.07839615643024445, + 0.041843291372060776, + 0.03743782639503479, + -0.007623815443366766, + -0.015687070786952972 + ] + }, + { + "id": "/en/baadasssss_cinema", + "initial_release_date": "2002-08-14", + "genre": [ + "Indie film", + "Documentary film", + "Blaxploitation film", + "Action/Adventure", + "Film & Television History", + "Biographical film" + ], + "directed_by": [ + "Isaac Julien" + ], + "name": "BaadAsssss Cinema", + "film_vector": [ + -0.4943872094154358, + 0.08048897981643677, + -0.20162445306777954, + 0.054013147950172424, + -0.2268531620502472, + -0.41038280725479126, + -0.0493621900677681, + -0.08488759398460388, + 0.16786256432533264, + -0.12662796676158905 + ] + }, + { + "id": "/en/baadasssss", + "initial_release_date": "2003-09-07", + "genre": [ + "Indie film", + "Biographical film", + "Docudrama", + "Historical period drama", + "Drama" + ], + "directed_by": [ + "Mario Van Peebles" + ], + "name": "Baadasssss!", + "film_vector": [ + -0.4503602385520935, + 0.1283247023820877, + -0.1879054605960846, + -0.04017382860183716, + -0.0847836434841156, + -0.3288814127445221, + -0.09172196686267853, + -0.014117692597210407, + 0.16548511385917664, + -0.2336944192647934 + ] + }, + { + "id": "/en/babel_2006", + "initial_release_date": "2006-05-23", + "genre": [ + "Indie film", + "Political drama", + "Drama" + ], + "directed_by": [ + "Alejandro Gonz\u00e1lez I\u00f1\u00e1rritu" + ], + "name": "Babel", + "film_vector": [ + -0.3302127718925476, + 0.1327926367521286, + -0.2236541509628296, + -0.1950906664133072, + -0.024170327931642532, + -0.18303389847278595, + -0.042470671236515045, + -0.015540230087935925, + 0.26211845874786377, + -0.189390629529953 + ] + }, + { + "id": "/en/baby_boy", + "initial_release_date": "2001-06-21", + "genre": [ + "Coming of age", + "Crime Fiction", + "Drama" + ], + "directed_by": [ + "John Singleton" + ], + "name": "Baby Boy", + "film_vector": [ + -0.29626592993736267, + -0.201805979013443, + -0.2379864752292633, + -0.12306025624275208, + -0.03129636496305466, + 0.1604498326778412, + -0.06958401203155518, + -0.20567184686660767, + 0.190066397190094, + -0.22534042596817017 + ] + }, + { + "id": "/en/back_by_midnight", + "initial_release_date": "2005-01-25", + "genre": [ + "Prison film", + "Comedy" + ], + "directed_by": [ + "Harry Basil" + ], + "name": "Back by Midnight", + "film_vector": [ + 0.028557004407048225, + -0.1719120591878891, + -0.19946858286857605, + 0.041866302490234375, + 0.24830113351345062, + -0.3036755919456482, + 0.11406467854976654, + -0.1315196007490158, + 0.03714292496442795, + -0.14716275036334991 + ] + }, + { + "id": "/en/back_to_school_with_franklin", + "initial_release_date": "2003-08-19", + "genre": [ + "Family", + "Animation", + "Educational film" + ], + "directed_by": [ + "Arna Selznick" + ], + "name": "Back to School with Franklin", + "film_vector": [ + 0.07699137181043625, + 0.022142035886645317, + -0.050380922853946686, + 0.28263312578201294, + -0.03296222165226936, + -0.036637745797634125, + -0.12985095381736755, + -0.20065085589885712, + 0.18033069372177124, + -0.1864660084247589 + ] + }, + { + "id": "/en/bad_boys_ii", + "initial_release_date": "2003-07-09", + "genre": [ + "Action Film", + "Crime Fiction", + "Thriller", + "Comedy" + ], + "directed_by": [ + "Michael Bay" + ], + "name": "Bad Boys II", + "film_vector": [ + -0.2683686912059784, + -0.2244810312986374, + -0.2581930160522461, + 0.12092871218919754, + 0.1112188771367073, + -0.137052983045578, + 0.02936827763915062, + -0.25726020336151123, + -0.11708499491214752, + -0.17334219813346863 + ] + }, + { + "id": "/wikipedia/ru_id/1598664", + "initial_release_date": "2002-04-26", + "genre": [ + "Spy film", + "Action/Adventure", + "Action Film", + "Thriller", + "Comedy" + ], + "directed_by": [ + "Joel Schumacher" + ], + "name": "Bad Company", + "film_vector": [ + -0.37622785568237305, + -0.2523559033870697, + -0.3223845958709717, + 0.11893106251955032, + 0.08115114271640778, + -0.15676845610141754, + 0.034548692405223846, + -0.18638962507247925, + -0.1827279031276703, + -0.09583340585231781 + ] + }, + { + "id": "/en/bad_education", + "initial_release_date": "2004-03-19", + "genre": [ + "Mystery", + "Drama" + ], + "directed_by": [ + "Pedro Almod\u00f3var" + ], + "name": "Bad Education", + "film_vector": [ + -0.0635652244091034, + -0.1351330429315567, + -0.1055079996585846, + -0.2715162932872772, + 0.11839272081851959, + 0.12463272362947464, + 0.05208950489759445, + -0.018814843147993088, + 0.046086762100458145, + -0.096307672560215 + ] + }, + { + "id": "/en/bad_eggs", + "genre": [ + "Comedy" + ], + "directed_by": [ + "Tony Martin" + ], + "name": "Bad Eggs", + "film_vector": [ + 0.14461922645568848, + -0.14097630977630615, + -0.2857373356819153, + 0.18403638899326324, + 0.04036053270101547, + -0.1285960078239441, + 0.3034844398498535, + -0.03473709896206856, + 0.0016797962598502636, + -0.1836121529340744 + ] + }, + { + "id": "/en/bad_news_bears", + "initial_release_date": "2005-07-22", + "genre": [ + "Family", + "Sports", + "Comedy" + ], + "directed_by": [ + "Richard Linklater" + ], + "name": "Bad News Bears", + "film_vector": [ + 0.14605844020843506, + -0.029043804854154587, + -0.19392235577106476, + 0.10079959034919739, + -0.3377330005168915, + 0.03759871423244476, + 0.06895880401134491, + -0.1909683644771576, + 0.034059662371873856, + -0.08451072126626968 + ] + }, + { + "id": "/en/bad_santa", + "initial_release_date": "2003-11-26", + "genre": [ + "Black comedy", + "Crime Fiction", + "Comedy" + ], + "directed_by": [ + "Terry Zwigoff" + ], + "name": "Bad Santa", + "film_vector": [ + -0.18049637973308563, + -0.1741621196269989, + -0.33937209844589233, + 0.03618704155087471, + -0.12437835335731506, + -0.09363112598657608, + 0.24334123730659485, + -0.08643095195293427, + -0.010125119239091873, + -0.3458814024925232 + ] + }, + { + "id": "/en/badal", + "initial_release_date": "2000-02-11", + "genre": [ + "Musical", + "Romance Film", + "Crime Fiction", + "Drama", + "Musical Drama" + ], + "directed_by": [ + "Raj Kanwar" + ], + "name": "Badal", + "film_vector": [ + -0.5455445647239685, + 0.14613857865333557, + -0.3799923062324524, + -0.10847748816013336, + -0.1287335753440857, + -0.03199288249015808, + -0.05633886158466339, + 0.054234735667705536, + 0.06116568297147751, + -0.12255252152681351 + ] + }, + { + "id": "/en/baghdad_er", + "initial_release_date": "2006-08-29", + "genre": [ + "Documentary film", + "Culture & Society", + "War film", + "Biographical film" + ], + "directed_by": [ + "Jon Alpert", + "Matthew O'Neill" + ], + "name": "Baghdad ER", + "film_vector": [ + -0.2474151849746704, + 0.08420658111572266, + 0.012628983706235886, + -0.10607102513313293, + -0.061204276978969574, + -0.4569791555404663, + -0.12561041116714478, + 0.021541502326726913, + 0.11930695921182632, + -0.10280207544565201 + ] + }, + { + "id": "/en/baise_moi", + "initial_release_date": "2000-06-28", + "genre": [ + "Erotica", + "Thriller", + "Erotic thriller", + "Art film", + "Romance Film", + "Drama", + "Road movie" + ], + "directed_by": [ + "Virginie Despentes", + "Coralie Trinh Thi" + ], + "name": "Baise Moi", + "film_vector": [ + -0.47905072569847107, + 0.09737751632928848, + -0.312049925327301, + -0.014695553109049797, + 0.10409592092037201, + -0.1636279821395874, + -0.020324472337961197, + 0.1146317720413208, + 0.11761528998613358, + -0.04992656409740448 + ] + }, + { + "id": "/en/bait_2000", + "initial_release_date": "2000-09-15", + "genre": [ + "Thriller", + "Crime Fiction", + "Adventure Film", + "Action Film", + "Action/Adventure", + "Crime Thriller", + "Comedy", + "Drama" + ], + "directed_by": [ + "Antoine Fuqua" + ], + "name": "Bait", + "film_vector": [ + -0.6135581731796265, + -0.24825778603553772, + -0.3642865717411041, + 0.031014421954751015, + -0.15809577703475952, + -0.1153351217508316, + -0.004384668078273535, + 0.010148831643164158, + -0.08522562682628632, + -0.04819944500923157 + ] + }, + { + "id": "/en/bala_2002", + "initial_release_date": "2002-12-13", + "genre": [ + "Drama", + "Tamil cinema", + "World cinema" + ], + "directed_by": [ + "Deepak" + ], + "name": "Bala", + "film_vector": [ + -0.5095080733299255, + 0.426471471786499, + 0.08572174608707428, + -0.10974068939685822, + -0.044797632843256, + -0.1350841522216797, + 0.04678076505661011, + -0.03342187777161598, + 0.07272617518901825, + -0.19942107796669006 + ] + }, + { + "id": "/en/ballistic_ecks_vs_sever", + "initial_release_date": "2002-09-20", + "genre": [ + "Spy film", + "Thriller", + "Action Film", + "Suspense", + "Action/Adventure", + "Action Thriller", + "Glamorized Spy Film" + ], + "directed_by": [ + "Wych Kaosayananda" + ], + "name": "Ballistic: Ecks vs. Sever", + "film_vector": [ + -0.4418410658836365, + -0.2534875273704529, + -0.1891995221376419, + 0.02258433774113655, + -0.05721791088581085, + -0.17389914393424988, + -0.05809875950217247, + -0.0408768430352211, + -0.2070806622505188, + 0.06260737776756287 + ] + }, + { + "id": "/en/balu_abcdefg", + "initial_release_date": "2005-01-06", + "genre": [ + "Romance Film", + "Tollywood", + "World cinema", + "Drama" + ], + "directed_by": [ + "A. Karunakaran" + ], + "name": "Balu ABCDEFG", + "film_vector": [ + -0.576160192489624, + 0.3958711624145508, + -0.10817086696624756, + 0.017272451892495155, + 0.12177379429340363, + -0.014586945995688438, + 0.11216937005519867, + -0.14386236667633057, + 0.03202945739030838, + -0.0842386856675148 + ] + }, + { + "id": "/en/balzac_and_the_little_chinese_seamstress_2002", + "initial_release_date": "2002-05-16", + "genre": [ + "Romance Film", + "Comedy-drama", + "Biographical film", + "Drama" + ], + "directed_by": [ + "Dai Sijie" + ], + "name": "The Little Chinese Seamstress", + "film_vector": [ + -0.1422501653432846, + 0.1602184921503067, + -0.34489208459854126, + 0.0606684610247612, + 0.2321828007698059, + -0.14326399564743042, + -0.089915931224823, + 0.03682029992341995, + 0.03733474761247635, + -0.32000812888145447 + ] + }, + { + "id": "/en/bambi_ii", + "initial_release_date": "2006-01-26", + "genre": [ + "Animation", + "Family", + "Adventure Film", + "Coming of age", + "Children's/Family", + "Family-Oriented Adventure" + ], + "directed_by": [ + "Brian Pimental" + ], + "name": "Bambi II", + "film_vector": [ + -0.17960020899772644, + 0.06479262560606003, + -0.10764789581298828, + 0.41575586795806885, + -0.13489750027656555, + -0.046835195273160934, + -0.1868971884250641, + -0.03221531957387924, + 0.10664680600166321, + -0.1578942835330963 + ] + }, + { + "id": "/en/bamboozled", + "initial_release_date": "2000-10-06", + "genre": [ + "Satire", + "Indie film", + "Music", + "Black comedy", + "Comedy-drama", + "Media Satire", + "Comedy", + "Drama" + ], + "directed_by": [ + "Spike Lee" + ], + "name": "Bamboozled", + "film_vector": [ + -0.2005833089351654, + 0.007160631939768791, + -0.410398006439209, + -0.13891983032226562, + -0.3349822163581848, + -0.25077661871910095, + 0.12490576505661011, + 0.09755759686231613, + 0.1368311643600464, + -0.11086298525333405 + ] + }, + { + "id": "/en/bandidas", + "initial_release_date": "2006-01-18", + "genre": [ + "Western", + "Action Film", + "Crime Fiction", + "Buddy film", + "Comedy", + "Adventure Film" + ], + "directed_by": [ + "Espen Sandberg", + "Joachim R\u00f8nning" + ], + "name": "Bandidas", + "film_vector": [ + -0.4588714838027954, + 0.12523753941059113, + -0.1488569676876068, + 0.23992501199245453, + -0.06437999755144119, + -0.2314869463443756, + 0.03711647540330887, + -0.2153739333152771, + -0.04711366444826126, + -0.17724722623825073 + ] + }, + { + "id": "/en/bandits", + "initial_release_date": "2001-10-12", + "genre": [ + "Romantic comedy", + "Crime Fiction", + "Buddy film", + "Romance Film", + "Heist film", + "Comedy", + "Drama" + ], + "directed_by": [ + "Barry Levinson" + ], + "name": "Bandits", + "film_vector": [ + -0.3781638443470001, + -0.139751136302948, + -0.46308445930480957, + 0.14510345458984375, + -0.018589867278933525, + -0.26596108078956604, + -0.0553060919046402, + -0.14500166475772858, + -0.1689620465040207, + -0.16153547167778015 + ] + }, + { + "id": "/en/bangaram", + "initial_release_date": "2006-05-03", + "genre": [ + "Action Film", + "Crime Fiction", + "Drama" + ], + "directed_by": [ + "Dharani" + ], + "name": "Bangaram", + "film_vector": [ + -0.4575485289096832, + 0.17137664556503296, + -0.03720059245824814, + -0.019857093691825867, + 0.04162757843732834, + -0.10296030342578888, + 0.14077243208885193, + -0.21671003103256226, + -0.0788036435842514, + -0.09359791874885559 + ] + }, + { + "id": "/en/bangkok_loco", + "initial_release_date": "2004-10-07", + "genre": [ + "Musical", + "Musical comedy", + "Comedy" + ], + "directed_by": [ + "Pornchai Hongrattanaporn" + ], + "name": "Bangkok Loco", + "film_vector": [ + -0.010058712214231491, + 0.18386095762252808, + -0.28217917680740356, + 0.09869098663330078, + 0.009127610363066196, + -0.1409977674484253, + 0.13379299640655518, + 0.0628984123468399, + -0.02568286843597889, + -0.035447780042886734 + ] + }, + { + "id": "/en/baran", + "initial_release_date": "2001-01-31", + "genre": [ + "Romance Film", + "Adventure Film", + "World cinema", + "Drama" + ], + "directed_by": [ + "Majid Majidi" + ], + "name": "Baran", + "film_vector": [ + -0.5962803363800049, + 0.32768845558166504, + -0.13480478525161743, + 0.07861994206905365, + 0.05571916326880455, + -0.12275795638561249, + 0.003028078004717827, + -0.1079186499118805, + 0.043340377509593964, + -0.1839752197265625 + ] + }, + { + "id": "/en/barbershop", + "initial_release_date": "2002-08-07", + "genre": [ + "Ensemble Film", + "Workplace Comedy", + "Comedy" + ], + "directed_by": [ + "Tim Story" + ], + "name": "Barbershop", + "film_vector": [ + 0.08077475428581238, + 0.05415056273341179, + -0.4163588881492615, + 0.163639098405838, + 0.11973665654659271, + -0.19161909818649292, + 0.18207165598869324, + -0.10156813263893127, + -0.08060397952795029, + -0.11503559350967407 + ] + }, + { + "id": "/en/bareback_mountain", + "genre": [ + "Pornographic film", + "Gay pornography" + ], + "directed_by": [ + "Afton Nills" + ], + "name": "Bareback Mountain", + "film_vector": [ + -0.03388475626707077, + -0.0011709406971931458, + -0.24007189273834229, + 0.08634929358959198, + 0.043131887912750244, + -0.2883952260017395, + -0.01129203848540783, + -0.04530814290046692, + 0.10511321574449539, + -0.0893920436501503 + ] + }, + { + "id": "/wikipedia/pt/Barnyard", + "initial_release_date": "2006-08-04", + "genre": [ + "Family", + "Animation", + "Comedy" + ], + "directed_by": [ + "Steve Oedekerk" + ], + "name": "Barnyard", + "film_vector": [ + 0.22417214512825012, + 0.1058761477470398, + -0.15315479040145874, + 0.3872978091239929, + -0.216740220785141, + 0.062172263860702515, + 0.07146881520748138, + -0.12439411878585815, + 0.12788887321949005, + -0.15904118120670319 + ] + }, + { + "id": "/en/barricade_2007", + "genre": [ + "Slasher", + "Horror" + ], + "directed_by": [ + "Timo Rose" + ], + "name": "Barricade", + "film_vector": [ + -0.17737317085266113, + -0.4562501013278961, + 0.0019356404663994908, + 0.04988432675600052, + 0.12271375954151154, + -0.08331938087940216, + 0.22605717182159424, + 0.00830685906112194, + 0.02449553832411766, + -0.01640160195529461 + ] + }, + { + "id": "/en/bas_itna_sa_khwaab_hai", + "initial_release_date": "2001-07-06", + "genre": [ + "Romance Film", + "Bollywood", + "World cinema" + ], + "directed_by": [ + "Goldie Behl" + ], + "name": "Bas Itna Sa Khwaab Hai", + "film_vector": [ + -0.49317866563796997, + 0.4113844633102417, + -0.18494951725006104, + 0.03132477030158043, + 0.24175730347633362, + -0.032608211040496826, + 0.1298193633556366, + -0.14626820385456085, + 0.024519111961126328, + -0.029943203553557396 + ] + }, + { + "id": "/en/basic_2003", + "initial_release_date": "2003-03-28", + "genre": [ + "Thriller", + "Action Film", + "Mystery" + ], + "directed_by": [ + "John McTiernan" + ], + "name": "Basic", + "film_vector": [ + -0.45393994450569153, + -0.3814134895801544, + -0.22670680284500122, + 0.141336128115654, + 0.2991114854812622, + -0.13227912783622742, + 0.04392436891794205, + -0.18981045484542847, + -0.013672616332769394, + -0.09851723909378052 + ] + }, + { + "id": "/en/basic_emotions", + "directed_by": [ + "Thomas Moon", + "Julie Pham", + "Georgia Lee" + ], + "initial_release_date": "2004-09-09", + "name": "Basic emotions", + "genre": [ + "Drama" + ], + "film_vector": [ + 0.02302301861345768, + 0.06873267889022827, + -0.20784950256347656, + -0.23844262957572937, + 0.05453477427363396, + 0.17151203751564026, + -0.05337557941675186, + 0.06207453832030296, + 0.07463712990283966, + -0.006031978875398636 + ] + }, + { + "id": "/en/basic_instinct_2", + "directed_by": [ + "Michael Caton-Jones" + ], + "initial_release_date": "2006-03-31", + "name": "Basic Instinct 2", + "genre": [ + "Thriller", + "Erotic thriller", + "Psychological thriller", + "Mystery", + "Crime Fiction", + "Horror" + ], + "film_vector": [ + -0.6324024200439453, + -0.3485163450241089, + -0.3128507733345032, + 0.060800254344940186, + -0.030678873881697655, + -0.036410409957170486, + 0.014872848987579346, + -0.040787212550640106, + 0.05121111869812012, + -0.037542179226875305 + ] + }, + { + "id": "/en/batalla_en_el_cielo", + "directed_by": [ + "Carlos Reygadas" + ], + "initial_release_date": "2005-05-15", + "name": "Battle In Heaven", + "genre": [ + "Drama" + ], + "film_vector": [ + 0.13332346081733704, + -0.04226423799991608, + 0.0032891223672777414, + -0.17670974135398865, + 0.083759605884552, + 0.11696361005306244, + -0.23639735579490662, + 0.09766634553670883, + -0.1595809906721115, + 0.005631785839796066 + ] + }, + { + "id": "/en/batman_begins", + "directed_by": [ + "Christopher Nolan" + ], + "initial_release_date": "2005-06-10", + "name": "Batman Begins", + "genre": [ + "Action Film", + "Crime Fiction", + "Adventure Film", + "Film noir", + "Drama" + ], + "film_vector": [ + -0.5328812599182129, + -0.15785157680511475, + -0.21545521914958954, + 0.09879949688911438, + -0.21554002165794373, + -0.1448960304260254, + -0.1335235834121704, + -0.10037950426340103, + -0.07327322661876678, + -0.19213716685771942 + ] + }, + { + "id": "/en/batman_beyond_return_of_the_joker", + "directed_by": [ + "Curt Geda" + ], + "initial_release_date": "2000-12-12", + "name": "Batman Beyond: Return of the Joker", + "genre": [ + "Science Fiction", + "Animation", + "Superhero movie", + "Action Film" + ], + "film_vector": [ + -0.274089515209198, + -0.13091102242469788, + -0.07556459307670593, + 0.30615168809890747, + -0.12661930918693542, + -0.08629819005727768, + -0.006965890526771545, + -0.14377164840698242, + -0.12259098887443542, + -0.09044187515974045 + ] + }, + { + "id": "/en/batman_dead_end", + "directed_by": [ + "Sandy Collora" + ], + "initial_release_date": "2003-07-19", + "name": "Batman: Dead End", + "genre": [ + "Indie film", + "Short Film", + "Fan film" + ], + "film_vector": [ + -0.22303546965122223, + -0.17420555651187897, + -0.1607438027858734, + 0.1566305160522461, + -0.023980502039194107, + -0.31375083327293396, + -0.017648249864578247, + -0.15330353379249573, + 0.07066559046506882, + -0.07685327529907227 + ] + }, + { + "id": "/en/batman_mystery_of_the_batwoman", + "directed_by": [ + "Curt Geda", + "Tim Maltby" + ], + "initial_release_date": "2003-10-21", + "name": "Batman: Mystery of the Batwoman", + "genre": [ + "Animated cartoon", + "Animation", + "Family", + "Superhero movie", + "Action/Adventure", + "Fantasy", + "Short Film", + "Fantasy Adventure" + ], + "film_vector": [ + -0.1669277548789978, + -0.10954698175191879, + -0.06121887266635895, + 0.34485557675361633, + -0.13169965147972107, + 0.0279849786311388, + -0.11297106742858887, + 0.010721869766712189, + -0.05827479064464569, + -0.19397881627082825 + ] + }, + { + "id": "/en/batoru_rowaiaru_ii_chinkonka", + "directed_by": [ + "Kenta Fukasaku", + "Kinji Fukasaku" + ], + "initial_release_date": "2003-07-05", + "name": "Battle Royale II: Requiem", + "genre": [ + "Thriller", + "Action Film", + "Science Fiction", + "Drama" + ], + "film_vector": [ + -0.3213784098625183, + -0.19634340703487396, + 0.04459090158343315, + 0.06844514608383179, + 0.24756911396980286, + -0.17616063356399536, + -0.16836906969547272, + -0.023712242022156715, + -0.12345561385154724, + -0.03182139992713928 + ] + }, + { + "id": "/en/battlefield_baseball", + "directed_by": [ + "Y\u016bdai Yamaguchi" + ], + "initial_release_date": "2003-07-19", + "name": "Battlefield Baseball", + "genre": [ + "Martial Arts Film", + "Horror", + "World cinema", + "Sports", + "Musical comedy", + "Japanese Movies", + "Horror comedy", + "Comedy" + ], + "film_vector": [ + -0.39754512906074524, + 0.02777961641550064, + -0.12418458610773087, + 0.15615440905094147, + -0.3329527974128723, + -0.12882012128829956, + -0.007585463114082813, + -0.05966334044933319, + 0.048922985792160034, + -0.008678456768393517 + ] + }, + { + "id": "/en/bbs_the_documentary", + "directed_by": [ + "Jason Scott Sadofsky" + ], + "name": "BBS: The Documentary", + "genre": [ + "Documentary film" + ], + "film_vector": [ + -4.546158015727997e-05, + 0.016436703503131866, + 0.11664261668920517, + -0.025198841467499733, + -0.1271606832742691, + -0.31492286920547485, + -0.14810192584991455, + -0.1149597093462944, + 0.13769380748271942, + -0.03136248141527176 + ] + }, + { + "id": "/en/be_cool", + "directed_by": [ + "F. Gary Gray" + ], + "initial_release_date": "2005-03-04", + "name": "Be Cool", + "genre": [ + "Crime Fiction", + "Crime Comedy", + "Comedy" + ], + "film_vector": [ + -0.32973673939704895, + -0.1818792074918747, + -0.3153928518295288, + -0.12158925086259842, + -0.3085371255874634, + -0.040733106434345245, + 0.1773395836353302, + -0.24035638570785522, + 0.0017694514244794846, + -0.23690463602542877 + ] + }, + { + "id": "/en/be_kind_rewind", + "directed_by": [ + "Michel Gondry" + ], + "initial_release_date": "2008-01-20", + "name": "Be Kind Rewind", + "genre": [ + "Farce", + "Comedy of Errors", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.0040811896324157715, + 0.03298686444759369, + -0.3998449444770813, + -0.10110968351364136, + -0.07681463658809662, + -0.02629677578806877, + 0.12445127964019775, + 0.24890120327472687, + -0.10968238115310669, + -0.12879568338394165 + ] + }, + { + "id": "/en/be_with_me", + "directed_by": [ + "Eric Khoo" + ], + "initial_release_date": "2005-05-12", + "name": "Be with Me", + "genre": [ + "Indie film", + "LGBT", + "World cinema", + "Art film", + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.5067089796066284, + 0.16243532299995422, + -0.3466370105743408, + 0.08012944459915161, + -0.11964968591928482, + -0.2078864872455597, + -0.04951900988817215, + -0.09644480794668198, + 0.3360188603401184, + -0.060696184635162354 + ] + }, + { + "id": "/en/beah_a_black_woman_speaks", + "directed_by": [ + "Lisa Gay Hamilton" + ], + "initial_release_date": "2003-08-22", + "name": "Beah: A Black Woman Speaks", + "genre": [ + "Documentary film", + "History", + "Biographical film" + ], + "film_vector": [ + 0.006559662986546755, + 0.090800940990448, + -0.04499552398920059, + -0.15086126327514648, + -0.06714732944965363, + -0.37196609377861023, + -0.0827081948518753, + -0.10282354056835175, + 0.14255593717098236, + -0.19211286306381226 + ] + }, + { + "id": "/en/beastly_boyz", + "directed_by": [ + "David DeCoteau" + ], + "name": "Beastly Boyz", + "genre": [ + "LGBT", + "Horror", + "B movie", + "Teen film" + ], + "film_vector": [ + -0.14591248333454132, + -0.10614658892154694, + -0.2570909559726715, + 0.27957117557525635, + 0.09477008134126663, + -0.1171654611825943, + -0.051903024315834045, + -0.07781319320201874, + 0.1943003535270691, + 0.017868876457214355 + ] + }, + { + "id": "/en/beauty_shop", + "directed_by": [ + "Bille Woodruff" + ], + "initial_release_date": "2005-03-24", + "name": "Beauty Shop", + "genre": [ + "Comedy" + ], + "film_vector": [ + 0.09022843837738037, + 0.06448011100292206, + -0.3224498927593231, + 0.0703774243593216, + 0.19215592741966248, + -0.044646285474300385, + 0.27409929037094116, + -0.06418150663375854, + 0.0749746561050415, + -0.1603253185749054 + ] + }, + { + "id": "/en/bedazzled_2000", + "directed_by": [ + "Harold Ramis" + ], + "initial_release_date": "2000-10-19", + "name": "Bedazzled", + "genre": [ + "Romantic comedy", + "Fantasy", + "Black comedy", + "Romance Film", + "Comedy" + ], + "film_vector": [ + -0.37047940492630005, + 0.06898367404937744, + -0.5548770427703857, + 0.07744671404361725, + 0.06510797142982483, + -0.1023583933711052, + 0.026403941214084625, + 0.10030030459165573, + 0.051712170243263245, + -0.22266444563865662 + ] + }, + { + "id": "/en/bee_movie", + "directed_by": [ + "Steve Hickner", + "Simon J. Smith" + ], + "initial_release_date": "2007-10-28", + "name": "Bee Movie", + "genre": [ + "Family", + "Adventure Film", + "Animation", + "Comedy" + ], + "film_vector": [ + -0.1427265852689743, + 0.13051921129226685, + -0.19087573885917664, + 0.4498368799686432, + -0.21098458766937256, + 0.003312434535473585, + -0.008155139163136482, + -0.09109362959861755, + 0.12401621788740158, + -0.12211737036705017 + ] + }, + { + "id": "/en/bee_season_2005", + "directed_by": [ + "David Siegel", + "Scott McGehee" + ], + "initial_release_date": "2005-11-11", + "name": "Bee Season", + "genre": [ + "Film adaptation", + "Coming of age", + "Family Drama", + "Drama" + ], + "film_vector": [ + -0.09149807691574097, + 0.14209407567977905, + -0.22973889112472534, + -0.04950231686234474, + -0.012417550198733807, + -0.001976043451577425, + -0.07519039511680603, + 0.05467711389064789, + 0.13067439198493958, + -0.10118403285741806 + ] + }, + { + "id": "/en/beer_league", + "directed_by": [ + "Frank Sebastiano" + ], + "initial_release_date": "2006-09-15", + "name": "Artie Lange's Beer League", + "genre": [ + "Sports", + "Indie film", + "Comedy" + ], + "film_vector": [ + 0.08415646851062775, + -0.0502246618270874, + -0.2601897716522217, + 0.036849360913038254, + -0.0722336620092392, + -0.31975990533828735, + 0.058082692325115204, + -0.21468251943588257, + 0.12510451674461365, + -0.11705448478460312 + ] + }, + { + "id": "/en/beer_the_movie", + "directed_by": [ + "Peter Hoare" + ], + "initial_release_date": "2006-05-16", + "name": "Beer: The Movie", + "genre": [ + "Indie film", + "Cult film", + "Parody", + "Bloopers & Candid Camera", + "Comedy" + ], + "film_vector": [ + -0.07607570290565491, + -0.051833540201187134, + -0.274078369140625, + 0.1108376681804657, + -0.20517598092556, + -0.4227840304374695, + 0.08349838107824326, + -0.08822368085384369, + 0.15835599601268768, + -0.06599009782075882 + ] + }, + { + "id": "/en/beerfest", + "directed_by": [ + "Jay Chandrasekhar" + ], + "initial_release_date": "2006-08-25", + "name": "Beerfest", + "genre": [ + "Absurdism", + "Comedy" + ], + "film_vector": [ + 0.19276654720306396, + -0.04163398966193199, + -0.28914034366607666, + -0.0506589338183403, + -0.22379210591316223, + -0.20690150558948517, + 0.26619040966033936, + 0.025487210601568222, + 0.04147679731249809, + -0.07767821848392487 + ] + }, + { + "id": "/en/before_night_falls_2001", + "directed_by": [ + "Julian Schnabel" + ], + "initial_release_date": "2000-09-03", + "name": "Before Night Falls", + "genre": [ + "LGBT", + "Gay Themed", + "Political drama", + "Gay", + "Gay Interest", + "Biographical film", + "Drama" + ], + "film_vector": [ + -0.2714864909648895, + 0.0054220519959926605, + -0.3217318058013916, + -0.06322841346263885, + 0.009854653850197792, + -0.15961900353431702, + -0.1688515692949295, + 0.09737429022789001, + 0.18934664130210876, + -0.1611400544643402 + ] + }, + { + "id": "/en/before_sunset", + "directed_by": [ + "Richard Linklater" + ], + "initial_release_date": "2004-02-10", + "name": "Before Sunset", + "genre": [ + "Romance Film", + "Indie film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.45868372917175293, + 0.06339095532894135, + -0.3711775243282318, + 0.07571113854646683, + 0.0895044133067131, + -0.15341231226921082, + -0.05762695521116257, + -0.07792261242866516, + 0.20346727967262268, + -0.07643583416938782 + ] + }, + { + "id": "/en/behind_enemy_lines", + "directed_by": [ + "John Moore" + ], + "initial_release_date": "2001-11-17", + "name": "Behind Enemy Lines", + "genre": [ + "Thriller", + "Action Film", + "War film", + "Action/Adventure", + "Drama" + ], + "film_vector": [ + -0.4506800174713135, + -0.156180739402771, + -0.20646589994430542, + 0.037822023034095764, + 0.05332888290286064, + -0.240097314119339, + -0.17522312700748444, + -0.08920171856880188, + -0.10735005140304565, + -0.11386989057064056 + ] + }, + { + "id": "/en/behind_the_mask_2006", + "directed_by": [ + "Shannon Keith" + ], + "initial_release_date": "2006-03-21", + "name": "Behind the Mask", + "genre": [ + "Documentary film", + "Indie film", + "Political cinema", + "Crime Fiction" + ], + "film_vector": [ + -0.4312637448310852, + -0.1629013866186142, + -0.1098717674612999, + -0.09109573811292648, + -0.1414845585823059, + -0.34941375255584717, + 0.009793835692107677, + -0.12255710363388062, + 0.2297818809747696, + -0.15296123921871185 + ] + }, + { + "id": "/en/behind_the_sun_2001", + "directed_by": [ + "Walter Salles" + ], + "initial_release_date": "2001-09-06", + "name": "Behind the Sun", + "genre": [ + "Drama" + ], + "film_vector": [ + 0.10864260792732239, + -0.0034738266840577126, + -0.0006099361926317215, + -0.24835583567619324, + 0.028296761214733124, + 0.08476307988166809, + -0.12534770369529724, + 0.05208335071802139, + -0.02267301455140114, + 0.07264217734336853 + ] + }, + { + "id": "/en/being_cyrus", + "directed_by": [ + "Homi Adajania" + ], + "initial_release_date": "2005-11-08", + "name": "Being Cyrus", + "genre": [ + "Thriller", + "Black comedy", + "Mystery", + "Psychological thriller", + "Crime Fiction", + "Drama" + ], + "film_vector": [ + -0.4843572974205017, + -0.20082545280456543, + -0.4158666133880615, + -0.07928244769573212, + -0.09765712916851044, + 0.013309701345860958, + -0.003136184299364686, + -0.030912205576896667, + 0.08434729278087616, + -0.12084583938121796 + ] + }, + { + "id": "/en/being_julia", + "directed_by": [ + "Istv\u00e1n Szab\u00f3" + ], + "initial_release_date": "2004-09-03", + "name": "Being Julia", + "genre": [ + "Romance Film", + "Romantic comedy", + "Comedy-drama", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.24183453619480133, + 0.0930381715297699, + -0.5270388126373291, + -0.021808376535773277, + 0.23024961352348328, + -0.056072115898132324, + -0.1297961175441742, + 0.1328292191028595, + 0.10641521215438843, + -0.17561398446559906 + ] + }, + { + "id": "/en/bekhals_tears", + "directed_by": [ + "Lauand Omar" + ], + "name": "Bekhal's Tears", + "genre": [ + "Drama" + ], + "film_vector": [ + 0.09597238898277283, + 0.12438653409481049, + -0.023310121148824692, + -0.22465434670448303, + 0.15603068470954895, + 0.15200795233249664, + -0.015257909893989563, + 0.061066288501024246, + 0.035091400146484375, + 0.020563652738928795 + ] + }, + { + "id": "/en/believe_in_me", + "directed_by": [ + "Robert Collector" + ], + "name": "Believe in Me", + "genre": [ + "Sports", + "Family Drama", + "Family", + "Drama" + ], + "film_vector": [ + -0.04984022676944733, + 0.10199227929115295, + -0.24467208981513977, + -0.12368659675121307, + -0.15620963275432587, + 0.24096006155014038, + -0.16541528701782227, + -0.17791640758514404, + 0.1048775464296341, + 0.13245147466659546 + ] + }, + { + "id": "/en/belly_of_the_beast", + "directed_by": [ + "Ching Siu-tung" + ], + "initial_release_date": "2003-12-30", + "name": "Belly of the Beast", + "genre": [ + "Action Film", + "Thriller", + "Political thriller", + "Martial Arts Film", + "Action/Adventure", + "Crime Thriller", + "Action Thriller", + "Chinese Movies" + ], + "film_vector": [ + -0.5090219974517822, + -0.13851337134838104, + -0.14428862929344177, + 0.2904841899871826, + -0.07486079633235931, + -0.2585222125053406, + -0.039592161774635315, + 0.020347364246845245, + -0.04878978431224823, + -0.009007740765810013 + ] + }, + { + "id": "/en/bellyful", + "directed_by": [ + "Melvin Van Peebles" + ], + "initial_release_date": "2000-06-28", + "name": "Bellyful", + "genre": [ + "Indie film", + "Satire", + "Comedy" + ], + "film_vector": [ + -0.1168709248304367, + 0.03618915006518364, + -0.35133981704711914, + 0.09624573588371277, + -0.00786050409078598, + -0.35046279430389404, + 0.2491058111190796, + -0.06249755993485451, + 0.1868494153022766, + -0.17615854740142822 + ] + }, + { + "id": "/en/bend_it_like_beckham", + "directed_by": [ + "Gurinder Chadha" + ], + "initial_release_date": "2002-04-11", + "name": "Bend It Like Beckham", + "genre": [ + "Coming of age", + "Indie film", + "Teen film", + "Sports", + "Romance Film", + "Comedy-drama", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.3178728222846985, + -0.009877551347017288, + -0.39301592111587524, + 0.10616343468427658, + -0.04626813903450966, + -0.17992350459098816, + -0.16843318939208984, + -0.1237235888838768, + 0.20233182609081268, + -0.009530803188681602 + ] + }, + { + "id": "/en/bendito_infierno", + "directed_by": [ + "Agust\u00edn D\u00edaz Yanes" + ], + "initial_release_date": "2001-11-28", + "name": "Don't Tempt Me", + "genre": [ + "Religious Film", + "Fantasy", + "Comedy" + ], + "film_vector": [ + -0.4179776608943939, + 0.1443629115819931, + -0.19767262041568756, + 0.23918482661247253, + -0.04629701375961304, + -0.07217313349246979, + 0.10078423470258713, + -0.05255403369665146, + 0.10100461542606354, + -0.2488768845796585 + ] + }, + { + "id": "/en/beneath", + "directed_by": [ + "Dagen Merrill" + ], + "initial_release_date": "2007-08-07", + "name": "Beneath", + "genre": [ + "Horror", + "Psychological thriller", + "Thriller", + "Supernatural", + "Crime Thriller" + ], + "film_vector": [ + -0.5660853385925293, + -0.3891088366508484, + -0.2606799304485321, + -0.05303163826465607, + -0.10977669060230255, + -0.018131177872419357, + 0.1248214840888977, + 0.21358352899551392, + 0.07182946801185608, + 0.02035488933324814 + ] + }, + { + "id": "/en/beneath_clouds", + "directed_by": [ + "Ivan Sen" + ], + "initial_release_date": "2002-02-08", + "name": "Beneath Clouds", + "genre": [ + "Indie film", + "Romance Film", + "Road movie", + "Social problem film", + "Drama" + ], + "film_vector": [ + -0.4678974151611328, + -0.009695872664451599, + -0.33050537109375, + 0.03208085149526596, + 0.05884114280343056, + -0.2887278199195862, + -0.09724864363670349, + -0.07000236213207245, + 0.23088723421096802, + 0.018458455801010132 + ] + }, + { + "id": "/en/beowulf_2007", + "directed_by": [ + "Robert Zemeckis" + ], + "initial_release_date": "2007-11-05", + "name": "Beowulf", + "genre": [ + "Adventure Film", + "Computer Animation", + "Fantasy", + "Action Film", + "Animation" + ], + "film_vector": [ + -0.3586614727973938, + 0.10813908278942108, + 0.10268222540616989, + 0.3865812420845032, + -0.17092986404895782, + -0.035697367042303085, + -0.18736302852630615, + 0.1298750936985016, + 0.05514608696103096, + -0.22488132119178772 + ] + }, + { + "id": "/en/beowulf_grendel", + "directed_by": [ + "Sturla Gunnarsson" + ], + "initial_release_date": "2005-09-14", + "name": "Beowulf & Grendel", + "genre": [ + "Adventure Film", + "Action Film", + "Fantasy", + "Action/Adventure", + "Film adaptation", + "World cinema", + "Historical period drama", + "Mythological Fantasy", + "Drama" + ], + "film_vector": [ + -0.4169957637786865, + 0.0414663590490818, + -0.09452126175165176, + 0.21049562096595764, + -0.2079584300518036, + -0.16893519461154938, + -0.23247158527374268, + 0.2460297793149948, + -0.049424413591623306, + -0.24840600788593292 + ] + }, + { + "id": "/en/best_in_show", + "directed_by": [ + "Christopher Guest" + ], + "initial_release_date": "2000-09-08", + "name": "Best in Show", + "genre": [ + "Comedy" + ], + "film_vector": [ + 0.18557578325271606, + 0.10022737830877304, + -0.30082881450653076, + 0.009276598691940308, + -0.1622299700975418, + -0.03424569219350815, + 0.30131569504737854, + -0.12668408453464508, + -0.07635719329118729, + -0.10615845024585724 + ] + }, + { + "id": "/en/the_best_of_the_bloodiest_brawls_vol_1", + "directed_by": [], + "initial_release_date": "2006-03-14", + "name": "The Best of The Bloodiest Brawls, Vol. 1", + "genre": [ + "Sports" + ], + "film_vector": [ + 0.07579454779624939, + -0.16835111379623413, + 0.11714440584182739, + -0.08930353820323944, + -0.04304664209485054, + -0.057885922491550446, + -0.02825402468442917, + -0.08891785889863968, + -0.1935284286737442, + 0.07717923074960709 + ] + }, + { + "id": "/en/better_luck_tomorrow", + "directed_by": [ + "Justin Lin" + ], + "initial_release_date": "2003-04-11", + "name": "Better Luck Tomorrow", + "genre": [ + "Coming of age", + "Teen film", + "Crime Fiction", + "Crime Drama", + "Drama" + ], + "film_vector": [ + -0.4221031069755554, + -0.1558617502450943, + -0.32884281873703003, + -0.05954289436340332, + -0.059477273374795914, + -0.013340894132852554, + -0.11684980988502502, + -0.2054676115512848, + 0.14639981091022491, + -0.094612717628479 + ] + }, + { + "id": "/en/bettie_page_dark_angel", + "directed_by": [ + "Nico B." + ], + "initial_release_date": "2004-02-11", + "name": "Bettie Page: Dark Angel", + "genre": [ + "Biographical film", + "Drama" + ], + "film_vector": [ + -0.06558658182621002, + -0.10520102083683014, + -0.0842776745557785, + -0.03130572661757469, + 0.1853300929069519, + -0.10235940665006638, + -0.0858275294303894, + -0.024817105382680893, + 0.11677175760269165, + -0.3575529456138611 + ] + }, + { + "id": "/en/bewitched_2005", + "directed_by": [ + "Nora Ephron" + ], + "initial_release_date": "2005-06-24", + "name": "Bewitched", + "genre": [ + "Romantic comedy", + "Fantasy", + "Romance Film", + "Comedy" + ], + "film_vector": [ + -0.24315473437309265, + 0.07394347339868546, + -0.5026160478591919, + 0.18025928735733032, + -0.012811251915991306, + 0.03551436588168144, + -0.03232201188802719, + 0.004780206363648176, + 0.02971399948000908, + -0.30738890171051025 + ] + }, + { + "id": "/en/beyond_borders", + "directed_by": [ + "Martin Campbell" + ], + "initial_release_date": "2003-10-24", + "name": "Beyond Borders", + "genre": [ + "Adventure Film", + "Historical period drama", + "Romance Film", + "War film", + "Drama" + ], + "film_vector": [ + -0.5404692888259888, + 0.10984839498996735, + -0.1261013150215149, + 0.10777075588703156, + -0.020604951307177544, + -0.21054035425186157, + -0.14967572689056396, + -0.008196084760129452, + 0.004022851586341858, + -0.2096991240978241 + ] + }, + { + "id": "/en/beyond_re-animator", + "directed_by": [ + "Brian Yuzna" + ], + "initial_release_date": "2003-04-04", + "name": "Beyond Re-Animator", + "genre": [ + "Horror", + "Science Fiction", + "Comedy" + ], + "film_vector": [ + -0.32766175270080566, + 0.006106775254011154, + 0.008748894557356834, + 0.3519326448440552, + -0.27010083198547363, + -0.02610437385737896, + 0.14302915334701538, + -0.10908588021993637, + 0.22938334941864014, + -0.14381495118141174 + ] + }, + { + "id": "/en/beyond_the_sea", + "directed_by": [ + "Kevin Spacey" + ], + "initial_release_date": "2004-09-11", + "name": "Beyond the Sea", + "genre": [ + "Musical", + "Music", + "Biographical film", + "Drama", + "Musical Drama" + ], + "film_vector": [ + -0.2601698338985443, + 0.09960833191871643, + -0.17936544120311737, + -0.006973564624786377, + -0.06878764927387238, + -0.19929984211921692, + -0.2220631092786789, + 0.23264476656913757, + 0.09616277366876602, + -0.18335776031017303 + ] + }, + { + "id": "/en/bhadra_2005", + "directed_by": [ + "Boyapati Srinu" + ], + "initial_release_date": "2005-05-12", + "name": "Bhadra", + "genre": [ + "Action Film", + "Tollywood", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.5760574340820312, + 0.3192785680294037, + 0.08048871904611588, + 0.013242267072200775, + 0.019995106384158134, + -0.14695948362350464, + 0.1399480104446411, + -0.1154489517211914, + -0.06536882370710373, + -0.047434430569410324 + ] + }, + { + "id": "/en/bhageeradha", + "directed_by": [ + "Rasool Ellore" + ], + "initial_release_date": "2005-10-13", + "name": "Bhageeratha", + "genre": [ + "Drama", + "Tollywood", + "World cinema" + ], + "film_vector": [ + -0.5276498794555664, + 0.3981872797012329, + 0.051872655749320984, + -0.07277783751487732, + -0.0435684509575367, + -0.130308136343956, + 0.17190757393836975, + -0.09166806191205978, + 0.008939212188124657, + -0.10896191745996475 + ] + }, + { + "id": "/en/bheema", + "directed_by": [ + "N. Lingusamy" + ], + "initial_release_date": "2008-01-14", + "name": "Bheemaa", + "genre": [ + "Action Film", + "Tamil cinema", + "World cinema" + ], + "film_vector": [ + -0.5034804344177246, + 0.37896594405174255, + 0.07845915108919144, + 0.07214049994945526, + 0.05698424577713013, + -0.18947143852710724, + 0.14209890365600586, + -0.11471156775951385, + -0.08261746168136597, + -0.07656794041395187 + ] + }, + { + "id": "/en/bhoot", + "directed_by": [ + "Ram Gopal Varma" + ], + "initial_release_date": "2003-05-17", + "name": "Bhoot", + "genre": [ + "Horror", + "Thriller", + "Bollywood", + "World cinema" + ], + "film_vector": [ + -0.6820937395095825, + 0.05198032408952713, + -0.08477011322975159, + 0.06495076417922974, + -0.02170642465353012, + -0.13312867283821106, + 0.2180590033531189, + -0.12384837865829468, + 0.11963068693876266, + -0.07209950685501099 + ] + }, + { + "id": "/en/bichhoo", + "directed_by": [ + "Guddu Dhanoa" + ], + "initial_release_date": "2000-07-07", + "name": "Bichhoo", + "genre": [ + "Thriller", + "Action Film", + "Crime Fiction", + "Bollywood", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.6878584623336792, + 0.1301562786102295, + -0.10468010604381561, + -0.03144094720482826, + -0.08072705566883087, + -0.10963381826877594, + 0.13436998426914215, + -0.11173909902572632, + 0.05460580065846443, + -0.12924370169639587 + ] + }, + { + "id": "/en/big_eden", + "directed_by": [ + "Thomas Bezucha" + ], + "initial_release_date": "2000-04-18", + "name": "Big Eden", + "genre": [ + "LGBT", + "Indie film", + "Romance Film", + "Comedy-drama", + "Gay", + "Gay Interest", + "Gay Themed", + "Romantic comedy", + "Drama" + ], + "film_vector": [ + -0.3309288024902344, + 0.0330548956990242, + -0.47744220495224, + 0.06061344966292381, + -0.027127845212817192, + -0.11118552088737488, + -0.16579869389533997, + 0.154531791806221, + 0.12593917548656464, + -0.02847435139119625 + ] + }, + { + "id": "/en/big_fat_liar", + "directed_by": [ + "Shawn Levy" + ], + "initial_release_date": "2002-02-02", + "name": "Big Fat Liar", + "genre": [ + "Family", + "Adventure Film", + "Comedy" + ], + "film_vector": [ + -0.05161666497588158, + -0.1201293021440506, + -0.27685225009918213, + 0.2750275433063507, + 0.042352840304374695, + -0.07810406386852264, + -0.012429403141140938, + -0.2417687028646469, + -0.04606873169541359, + -0.2524885833263397 + ] + }, + { + "id": "/en/big_fish", + "directed_by": [ + "Tim Burton" + ], + "initial_release_date": "2003-12-10", + "name": "Big Fish", + "genre": [ + "Fantasy", + "Adventure Film", + "War film", + "Comedy-drama", + "Film adaptation", + "Family Drama", + "Fantasy Comedy", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.3791501224040985, + 0.06322411447763443, + -0.3184550404548645, + 0.23172755539417267, + -0.2235385775566101, + -0.20025043189525604, + -0.12829697132110596, + 0.15884466469287872, + -0.120340496301651, + -0.1377057284116745 + ] + }, + { + "id": "/en/big_girls_dont_cry_2002", + "directed_by": [ + "Maria von Heland" + ], + "initial_release_date": "2002-10-24", + "name": "Big Girls Don't Cry", + "genre": [ + "World cinema", + "Melodrama", + "Teen film", + "Drama" + ], + "film_vector": [ + -0.3661530017852783, + 0.14753742516040802, + -0.29980969429016113, + 0.036215271800756454, + 0.05908792093396187, + -0.06097271665930748, + -0.05077138543128967, + -0.11739130318164825, + 0.2904341220855713, + -0.09394341707229614 + ] + }, + { + "id": "/en/big_man_little_love", + "directed_by": [ + "Handan \u0130pek\u00e7i" + ], + "initial_release_date": "2001-10-19", + "name": "Big Man, Little Love", + "genre": [ + "Drama" + ], + "film_vector": [ + 0.16636793315410614, + 0.08305419981479645, + -0.27341824769973755, + -0.15744057297706604, + 0.17652395367622375, + 0.16141590476036072, + -0.08890735357999802, + -0.051770057529211044, + -0.04579504579305649, + 0.03145520016551018 + ] + }, + { + "id": "/en/big_mommas_house", + "directed_by": [ + "Raja Gosnell" + ], + "initial_release_date": "2000-05-31", + "name": "Big Momma's House", + "genre": [ + "Action Film", + "Crime Fiction", + "Comedy" + ], + "film_vector": [ + -0.0652594044804573, + -0.1847754418849945, + -0.2858797311782837, + 0.14073586463928223, + 0.10632110387086868, + -0.1521388739347458, + 0.07397639006376266, + -0.20905405282974243, + -0.038164325058460236, + -0.20766295492649078 + ] + }, + { + "id": "/en/big_mommas_house_2", + "directed_by": [ + "John Whitesell" + ], + "initial_release_date": "2006-01-26", + "name": "Big Momma's House 2", + "genre": [ + "Crime Fiction", + "Slapstick", + "Action Film", + "Action/Adventure", + "Thriller", + "Farce", + "Comedy" + ], + "film_vector": [ + -0.27655017375946045, + -0.19549456238746643, + -0.41401779651641846, + 0.17465713620185852, + -0.055571094155311584, + -0.14933869242668152, + 0.11718860268592834, + -0.12251229584217072, + -0.05057315528392792, + -0.127732515335083 + ] + }, + { + "id": "/en/big_toys_no_boys_2", + "directed_by": [ + "Trist\u00e1n" + ], + "name": "Big Toys, No Boys 2", + "genre": [ + "Pornographic film" + ], + "film_vector": [ + -0.1038442999124527, + 0.08415830135345459, + -0.2314249873161316, + 0.24890248477458954, + 0.058009322732686996, + -0.13518236577510834, + 0.04891311004757881, + -0.10574530065059662, + 0.1849644035100937, + -0.048717327415943146 + ] + }, + { + "id": "/en/big_trouble_2002", + "directed_by": [ + "Barry Sonnenfeld" + ], + "initial_release_date": "2002-04-05", + "name": "Big Trouble", + "genre": [ + "Crime Fiction", + "Black comedy", + "Action Film", + "Action/Adventure", + "Gangster Film", + "Comedy" + ], + "film_vector": [ + -0.3238034248352051, + -0.16685734689235687, + -0.3492041230201721, + -0.03149101883172989, + -0.1126043051481247, + -0.22007475793361664, + 0.01050802506506443, + -0.22049646079540253, + -0.1900782287120819, + -0.23400668799877167 + ] + }, + { + "id": "/en/bigger_than_the_sky", + "directed_by": [ + "Al Corley" + ], + "initial_release_date": "2005-02-18", + "name": "Bigger Than the Sky", + "genre": [ + "Romantic comedy", + "Romance Film", + "Comedy-drama", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.25252822041511536, + 0.11878012865781784, + -0.48661383986473083, + 0.055648207664489746, + 0.15575659275054932, + -0.08181019127368927, + -0.12933264672756195, + 0.08985204994678497, + -0.06163822114467621, + -0.08856352418661118 + ] + }, + { + "id": "/en/biggie_tupac", + "directed_by": [ + "Nick Broomfield" + ], + "initial_release_date": "2002-01-11", + "name": "Biggie & Tupac", + "genre": [ + "Documentary film", + "Hip hop film", + "Rockumentary", + "Indie film", + "Crime Fiction", + "True crime", + "Biographical film" + ], + "film_vector": [ + -0.38463178277015686, + -0.09711763262748718, + -0.27451246976852417, + -0.03263331949710846, + -0.2026958167552948, + -0.44779038429260254, + -0.08992628753185272, + -0.09333804994821548, + 0.020316269248723984, + -0.0330386720597744 + ] + }, + { + "id": "/en/bill_2007", + "directed_by": [ + "Bernie Goldmann", + "Melisa Wallick" + ], + "initial_release_date": "2007-09-08", + "name": "Meet Bill", + "genre": [ + "Romantic comedy", + "Romance Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.2528170347213745, + 0.011597037315368652, + -0.5688733458518982, + 0.10135436803102493, + 0.06467542052268982, + -0.11627203226089478, + -0.015146955847740173, + -0.08035476505756378, + -0.0681818351149559, + -0.09681202471256256 + ] + }, + { + "id": "/en/billy_elliot", + "directed_by": [ + "Stephen Daldry" + ], + "initial_release_date": "2000-05-19", + "name": "Billy Elliot", + "genre": [ + "Comedy", + "Music", + "Drama" + ], + "film_vector": [ + -0.13330823183059692, + 0.05476929992437363, + -0.34969836473464966, + -0.04683307930827141, + -0.027158454060554504, + -0.09807004779577255, + -0.04457373917102814, + -0.002756816567853093, + 0.14953304827213287, + -0.2250927984714508 + ] + }, + { + "id": "/en/bionicle_3_web_of_shadows", + "directed_by": [ + "David Molina", + "Terry Shakespeare" + ], + "initial_release_date": "2005-10-11", + "name": "Bionicle 3: Web of Shadows", + "genre": [ + "Fantasy", + "Adventure Film", + "Animation", + "Family", + "Computer Animation", + "Science Fiction" + ], + "film_vector": [ + -0.30382204055786133, + -0.13542711734771729, + 0.09070334583520889, + 0.41312140226364136, + -0.13205763697624207, + 0.04404734820127487, + -0.13052955269813538, + 0.001512482762336731, + 0.04370342195034027, + -0.02613525092601776 + ] + }, + { + "id": "/en/bionicle_2_legends_of_metru_nui", + "directed_by": [ + "David Molina", + "Terry Shakespeare" + ], + "initial_release_date": "2004-10-19", + "name": "Bionicle 2: Legends of Metru Nui", + "genre": [ + "Fantasy", + "Adventure Film", + "Animation", + "Family", + "Computer Animation", + "Science Fiction", + "Children's Fantasy", + "Children's/Family", + "Fantasy Adventure" + ], + "film_vector": [ + -0.17500120401382446, + 0.04721704497933388, + 0.11600036919116974, + 0.4410300850868225, + -0.0498059019446373, + 0.09629756212234497, + -0.13370925188064575, + -0.014162527397274971, + -0.018377428874373436, + -0.015352590009570122 + ] + }, + { + "id": "/en/bionicle_mask_of_light", + "directed_by": [ + "David Molina", + "Terry Shakespeare" + ], + "initial_release_date": "2003-09-16", + "name": "Bionicle: Mask of Light: The Movie", + "genre": [ + "Family", + "Fantasy", + "Animation", + "Adventure Film", + "Computer Animation", + "Science Fiction", + "Children's Fantasy", + "Children's/Family", + "Fantasy Adventure" + ], + "film_vector": [ + -0.10403140634298325, + -0.12128980457782745, + 0.1177547350525856, + 0.4005366563796997, + 0.02166767790913582, + -0.001987062394618988, + -0.12343789637088776, + 0.06421872228384018, + 0.03179415315389633, + -0.0593363381922245 + ] + }, + { + "id": "/en/birth_2004", + "directed_by": [ + "Jonathan Glazer" + ], + "initial_release_date": "2004-09-08", + "name": "Birth", + "genre": [ + "Mystery", + "Indie film", + "Romance Film", + "Thriller", + "Drama" + ], + "film_vector": [ + -0.5302066802978516, + -0.1505151093006134, + -0.39133965969085693, + 0.0570557527244091, + 0.10921945422887802, + -0.1832370162010193, + -0.042314451187849045, + -0.10824361443519592, + 0.21333754062652588, + -0.058778684586286545 + ] + }, + { + "id": "/en/birthday_girl", + "directed_by": [ + "Jez Butterworth" + ], + "initial_release_date": "2002-02-01", + "name": "Birthday Girl", + "genre": [ + "Black comedy", + "Thriller", + "Indie film", + "Erotic thriller", + "Crime Fiction", + "Romance Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.5020525455474854, + -0.11868255585432053, + -0.5180292129516602, + 0.08462436497211456, + 0.033500585705041885, + -0.08399996161460876, + 0.026104604825377464, + -0.05146688595414162, + 0.15654700994491577, + -0.04618874192237854 + ] + }, + { + "id": "/en/bite_me_fanboy", + "directed_by": [ + "Mat Nastos" + ], + "initial_release_date": "2005-06-01", + "name": "Bite Me, Fanboy", + "genre": [ + "Comedy" + ], + "film_vector": [ + 0.08259804546833038, + 0.036152150481939316, + -0.26573801040649414, + 0.06377754360437393, + -0.08196884393692017, + -0.004111336078494787, + 0.16853399574756622, + -0.08643373847007751, + -0.029064275324344635, + -0.0643642246723175 + ] + }, + { + "id": "/en/bitter_jester", + "directed_by": [ + "Maija DiGiorgio" + ], + "initial_release_date": "2003-02-26", + "name": "Bitter Jester", + "genre": [ + "Indie film", + "Documentary film", + "Stand-up comedy", + "Culture & Society", + "Comedy", + "Biographical film" + ], + "film_vector": [ + -0.08511412143707275, + -0.016065286472439766, + -0.3871217668056488, + -0.0434570387005806, + -0.16855759918689728, + -0.4736183285713196, + 0.15193118155002594, + -0.017349353060126305, + 0.11173641681671143, + -0.15482088923454285 + ] + }, + { + "id": "/en/black_2005", + "directed_by": [ + "Sanjay Leela Bhansali" + ], + "initial_release_date": "2005-02-04", + "name": "Black", + "genre": [ + "Family", + "Drama" + ], + "film_vector": [ + 0.1576983630657196, + -0.038375355303287506, + -0.20628070831298828, + -0.28627172112464905, + 0.0256346445530653, + 0.18582239747047424, + -0.05752750486135483, + -0.12357951700687408, + 0.021803461015224457, + -0.052460797131061554 + ] + }, + { + "id": "/en/black_and_white_2002", + "directed_by": [ + "Craig Lahiff" + ], + "initial_release_date": "2002-10-31", + "name": "Black and White", + "genre": [ + "Trial drama", + "Crime Fiction", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.4178834557533264, + -0.007474580779671669, + -0.10464976727962494, + -0.3286390006542206, + -0.25940749049186707, + -0.09294044226408005, + 0.021066132932901382, + -0.07735253870487213, + 0.07050494104623795, + -0.37562352418899536 + ] + }, + { + "id": "/en/black_book_2006", + "directed_by": [ + "Paul Verhoeven" + ], + "initial_release_date": "2006-09-01", + "name": "Black Book", + "genre": [ + "Thriller", + "War film", + "Drama" + ], + "film_vector": [ + -0.4735225737094879, + -0.2206914871931076, + -0.1821955144405365, + -0.19154992699623108, + -0.02349427342414856, + -0.15658046305179596, + -0.032790057361125946, + -0.132257342338562, + 0.019353799521923065, + -0.27909761667251587 + ] + }, + { + "id": "/wikipedia/fr/Black_Christmas_$0028film$002C_2006$0029", + "directed_by": [ + "Glen Morgan" + ], + "initial_release_date": "2006-12-15", + "name": "Black Christmas", + "genre": [ + "Slasher", + "Teen film", + "Horror", + "Thriller" + ], + "film_vector": [ + -0.25892484188079834, + -0.32396048307418823, + -0.21643251180648804, + 0.13305044174194336, + 0.19650191068649292, + -0.10063419491052628, + 0.16296201944351196, + 0.007532956078648567, + 0.16473931074142456, + -0.08099925518035889 + ] + }, + { + "id": "/en/black_cloud", + "directed_by": [ + "Ricky Schroder" + ], + "initial_release_date": "2004-04-30", + "name": "Black Cloud", + "genre": [ + "Indie film", + "Sports", + "Drama" + ], + "film_vector": [ + -0.23954036831855774, + -0.11673159897327423, + -0.14884325861930847, + -0.10012180358171463, + 0.017111709341406822, + -0.14053761959075928, + -0.10556405782699585, + -0.22631007432937622, + 0.1298981010913849, + -0.02562606707215309 + ] + }, + { + "id": "/en/black_friday_1993", + "directed_by": [ + "Anurag Kashyap" + ], + "initial_release_date": "2004-05-20", + "name": "Black Friday", + "genre": [ + "Crime Fiction", + "Historical drama", + "Drama" + ], + "film_vector": [ + -0.21780839562416077, + -0.25762268900871277, + -0.13357475399971008, + -0.29621267318725586, + -0.149135023355484, + 0.03340098261833191, + -0.05042354762554169, + -0.043398160487413406, + -0.0313902273774147, + -0.2760515511035919 + ] + }, + { + "id": "/en/black_hawk_down", + "directed_by": [ + "Ridley Scott" + ], + "initial_release_date": "2001-12-18", + "name": "Black Hawk Down", + "genre": [ + "War film", + "Action/Adventure", + "Action Film", + "History", + "Combat Films", + "Drama" + ], + "film_vector": [ + -0.3716319501399994, + -0.12488815933465958, + -0.034001752734184265, + 0.10170410573482513, + -0.16592462360858917, + -0.3238954544067383, + -0.20147709548473358, + -0.07192911952733994, + -0.16437552869319916, + -0.09504402428865433 + ] + }, + { + "id": "/en/black_hole_2006", + "directed_by": [ + "Tibor Tak\u00e1cs" + ], + "initial_release_date": "2006-06-10", + "name": "The Black Hole", + "genre": [ + "Science Fiction", + "Thriller", + "Television film" + ], + "film_vector": [ + -0.22242607176303864, + -0.2532239854335785, + -0.032368868589401245, + -0.023848360404372215, + 0.12210719287395477, + -0.18911424279212952, + 0.09962378442287445, + -0.09012836962938309, + -0.009870944544672966, + -0.09250542521476746 + ] + }, + { + "id": "/en/black_knight_2001", + "directed_by": [ + "Gil Junger" + ], + "initial_release_date": "2001-11-15", + "name": "Black Knight", + "genre": [ + "Time travel", + "Adventure Film", + "Costume drama", + "Science Fiction", + "Fantasy", + "Adventure Comedy", + "Fantasy Comedy", + "Comedy" + ], + "film_vector": [ + -0.29740482568740845, + -0.024102505296468735, + -0.19106915593147278, + 0.18694990873336792, + -0.27564820647239685, + -0.06601335853338242, + -0.02036113850772381, + 0.07352045178413391, + -0.09162670373916626, + -0.2571293115615845 + ] + }, + { + "id": "/en/blackball_2005", + "directed_by": [ + "Mel Smith" + ], + "initial_release_date": "2005-02-11", + "name": "Blackball", + "genre": [ + "Sports", + "Family Drama", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.1490200161933899, + 0.06228335574269295, + -0.3343677520751953, + -0.18610021471977234, + -0.35232096910476685, + 0.08129789680242538, + -0.03952375799417496, + -0.22414979338645935, + 0.05544588714838028, + -0.0430513396859169 + ] + }, + { + "id": "/en/blackwoods", + "directed_by": [ + "Uwe Boll" + ], + "name": "Blackwoods", + "genre": [ + "Thriller", + "Crime Thriller", + "Psychological thriller", + "Drama" + ], + "film_vector": [ + -0.5465282201766968, + -0.26097387075424194, + -0.2857346534729004, + -0.1710096299648285, + -0.050301022827625275, + -0.026941854506731033, + 0.10369548201560974, + 0.05571074038743973, + 0.00844646617770195, + -0.08998943120241165 + ] + }, + { + "id": "/en/blade_ii", + "directed_by": [ + "Guillermo del Toro" + ], + "initial_release_date": "2002-03-21", + "name": "Blade II", + "genre": [ + "Thriller", + "Horror", + "Science Fiction", + "Action Film" + ], + "film_vector": [ + -0.4074249267578125, + -0.3264487683773041, + -0.006877638399600983, + 0.1418972760438919, + 0.2387068271636963, + -0.182667076587677, + -0.05662725865840912, + -0.05820813402533531, + -0.06068284437060356, + 0.05775785073637962 + ] + }, + { + "id": "/en/blade_trinity", + "directed_by": [ + "David S. Goyer" + ], + "initial_release_date": "2004-12-07", + "name": "Blade: Trinity", + "genre": [ + "Thriller", + "Action Film", + "Horror", + "Action/Adventure", + "Superhero movie", + "Fantasy", + "Adventure Film", + "Action Thriller" + ], + "film_vector": [ + -0.432682603597641, + -0.2775305509567261, + -0.1121571734547615, + 0.13697589933872223, + 0.05685955658555031, + -0.12288609892129898, + -0.11088701337575912, + 0.041635286062955856, + -0.0886458307504654, + 0.07810908555984497 + ] + }, + { + "id": "/en/bleach_memories_of_nobody", + "directed_by": [ + "Noriyuki Abe" + ], + "initial_release_date": "2006-12-16", + "name": "Bleach: Memories of Nobody", + "genre": [ + "Anime", + "Fantasy", + "Animation", + "Action Film", + "Adventure Film" + ], + "film_vector": [ + -0.24415621161460876, + -0.033925849944353104, + 0.021131984889507294, + 0.31688767671585083, + 0.06903619319200516, + -0.05184761807322502, + 0.000802147900685668, + -0.028635095804929733, + 0.14206190407276154, + -0.10900647193193436 + ] + }, + { + "id": "/en/bless_the_child", + "directed_by": [ + "Chuck Russell" + ], + "initial_release_date": "2000-08-11", + "name": "Bless the Child", + "genre": [ + "Horror", + "Crime Fiction", + "Drama", + "Thriller" + ], + "film_vector": [ + -0.4338729977607727, + -0.22328534722328186, + -0.19864673912525177, + 0.04731814190745354, + -0.14572186768054962, + 0.111391082406044, + 0.047077521681785583, + -0.014424558728933334, + 0.24631693959236145, + -0.24332866072654724 + ] + }, + { + "id": "/en/blind_shaft", + "directed_by": [ + "Li Yang" + ], + "initial_release_date": "2003-02-12", + "name": "Blind Shaft", + "genre": [ + "Crime Fiction", + "Drama" + ], + "film_vector": [ + -0.2728862166404724, + -0.21916256844997406, + -0.056742485612630844, + -0.22384145855903625, + -0.03232826665043831, + -0.011913450434803963, + 0.1075233519077301, + -0.09518757462501526, + 0.07933828234672546, + -0.32585740089416504 + ] + }, + { + "id": "/en/blissfully_yours", + "directed_by": [ + "Apichatpong Weerasethakul" + ], + "initial_release_date": "2002-05-17", + "name": "Blissfully Yours", + "genre": [ + "Erotica", + "Romance Film", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.4879608154296875, + 0.24134254455566406, + -0.2116163671016693, + 0.013517765328288078, + -0.05838342756032944, + -0.03560328856110573, + 0.008589638397097588, + -0.0336986742913723, + 0.30253422260284424, + -0.15663886070251465 + ] + }, + { + "id": "/en/blood_of_a_champion", + "directed_by": [ + "Lawrence Page" + ], + "initial_release_date": "2006-03-07", + "name": "Blood of a Champion", + "genre": [ + "Crime Fiction", + "Sports", + "Drama" + ], + "film_vector": [ + -0.21919259428977966, + -0.17408737540245056, + 0.041506797075271606, + -0.2577030658721924, + -0.06319471448659897, + 0.06620299816131592, + -0.1361164152622223, + -0.1372121423482895, + -0.07181951403617859, + -0.22988790273666382 + ] + }, + { + "id": "/en/blood_rain", + "directed_by": [ + "Kim Dae-seung" + ], + "initial_release_date": "2005-05-04", + "name": "Blood Rain", + "genre": [ + "Thriller", + "Mystery", + "East Asian cinema", + "World cinema" + ], + "film_vector": [ + -0.5668721199035645, + -0.09737057983875275, + 0.0014743574429303408, + 0.0508190393447876, + 0.09816153347492218, + -0.15993979573249817, + 0.09230568259954453, + -0.04019245505332947, + 0.13788825273513794, + -0.1846090853214264 + ] + }, + { + "id": "/en/blood_work", + "directed_by": [ + "Clint Eastwood" + ], + "initial_release_date": "2002-08-09", + "name": "Blood Work", + "genre": [ + "Mystery", + "Crime Thriller", + "Thriller", + "Suspense", + "Crime Fiction", + "Detective fiction", + "Drama" + ], + "film_vector": [ + -0.5227272510528564, + -0.3594683110713959, + -0.23099693655967712, + -0.18467172980308533, + -0.057406120002269745, + 0.01615399308502674, + 0.0498104989528656, + 0.10953027009963989, + -0.041962672024965286, + -0.13774096965789795 + ] + }, + { + "id": "/en/bloodrayne_2006", + "directed_by": [ + "Uwe Boll" + ], + "initial_release_date": "2005-10-23", + "name": "BloodRayne", + "genre": [ + "Horror", + "Action Film", + "Fantasy", + "Adventure Film", + "Costume drama" + ], + "film_vector": [ + -0.5522557497024536, + -0.11416007578372955, + -0.023219045251607895, + 0.23945671319961548, + -0.06501598656177521, + -0.06597384810447693, + -0.0003857472911477089, + 0.025089222937822342, + 0.11572068929672241, + -0.16661834716796875 + ] + }, + { + "id": "/en/bloodsport_ecws_most_violent_matches", + "directed_by": [], + "initial_release_date": "2006-02-07", + "name": "Bloodsport - ECW's Most Violent Matches", + "genre": [ + "Documentary film", + "Sports" + ], + "film_vector": [ + -0.04881000891327858, + -0.1494332104921341, + 0.1620457023382187, + -0.0695660188794136, + 0.023058583959937096, + -0.24487623572349548, + -0.09497766941785812, + -0.10608309507369995, + -0.01773385889828205, + 0.09858356416225433 + ] + }, + { + "id": "/en/bloody_sunday", + "directed_by": [ + "Paul Greengrass" + ], + "initial_release_date": "2002-01-16", + "name": "Bloody Sunday", + "genre": [ + "Political drama", + "Docudrama", + "Historical fiction", + "War film", + "Drama" + ], + "film_vector": [ + -0.31864121556282043, + -0.033820562064647675, + -0.006447996478527784, + -0.19159841537475586, + -0.12594826519489288, + -0.1984245330095291, + -0.12850727140903473, + 0.10521599650382996, + 0.02276272512972355, + -0.24223411083221436 + ] + }, + { + "id": "/en/blow", + "directed_by": [ + "Ted Demme" + ], + "initial_release_date": "2001-03-29", + "name": "Blow", + "genre": [ + "Biographical film", + "Crime Fiction", + "Film adaptation", + "Historical period drama", + "Drama" + ], + "film_vector": [ + -0.4511127471923828, + -0.014616023749113083, + -0.13918831944465637, + -0.1852971911430359, + -0.16614237427711487, + -0.19116759300231934, + -0.12495794892311096, + -0.02887628972530365, + -0.011553773656487465, + -0.33133816719055176 + ] + }, + { + "id": "/en/blue_car", + "directed_by": [ + "Karen Moncrieff" + ], + "initial_release_date": "2003-05-02", + "name": "Blue Car", + "genre": [ + "Indie film", + "Family Drama", + "Coming of age", + "Drama" + ], + "film_vector": [ + -0.28233110904693604, + -0.007445259019732475, + -0.38534510135650635, + 0.03998855873942375, + 0.03919827938079834, + -0.09960468113422394, + -0.14826719462871552, + -0.20450538396835327, + 0.2229415625333786, + -0.05094537138938904 + ] + }, + { + "id": "/en/blue_collar_comedy_tour_rides_again", + "directed_by": [ + "C. B. Harding" + ], + "initial_release_date": "2004-12-05", + "name": "Blue Collar Comedy Tour Rides Again", + "genre": [ + "Documentary film", + "Stand-up comedy", + "Comedy" + ], + "film_vector": [ + 0.06341668218374252, + 0.05776827409863472, + -0.3672117590904236, + -0.02611907757818699, + -0.28918617963790894, + -0.3423541188240051, + 0.1828777939081192, + -0.13634252548217773, + -0.005010778084397316, + -0.08488575369119644 + ] + }, + { + "id": "/en/blue_collar_comedy_tour_one_for_the_road", + "directed_by": [ + "C. B. Harding" + ], + "initial_release_date": "2006-06-27", + "name": "Blue Collar Comedy Tour: One for the Road", + "genre": [ + "Stand-up comedy", + "Concert film", + "Comedy" + ], + "film_vector": [ + 0.13247472047805786, + 0.05241373926401138, + -0.4049503803253174, + -0.04964858293533325, + -0.20602169632911682, + -0.3031204342842102, + 0.19131478667259216, + -0.15403035283088684, + -0.06710860133171082, + -0.052558399736881256 + ] + }, + { + "id": "/en/blue_collar_comedy_tour_the_movie", + "directed_by": [ + "C. B. Harding" + ], + "initial_release_date": "2003-03-28", + "name": "Blue Collar Comedy Tour: The Movie", + "genre": [ + "Stand-up comedy", + "Documentary film", + "Comedy" + ], + "film_vector": [ + 0.1607953906059265, + 0.07401486486196518, + -0.34431952238082886, + -0.0855281800031662, + -0.26718106865882874, + -0.3930073380470276, + 0.19235920906066895, + -0.1466539055109024, + -0.04281450808048248, + -0.080543152987957 + ] + }, + { + "id": "/en/blue_crush", + "directed_by": [ + "John Stockwell" + ], + "initial_release_date": "2002-08-08", + "name": "Blue Crush", + "genre": [ + "Teen film", + "Romance Film", + "Sports", + "Drama" + ], + "film_vector": [ + -0.3026648461818695, + 0.010627655312418938, + -0.35415008664131165, + 0.18087303638458252, + 0.07206156849861145, + 0.04199700802564621, + -0.19919277727603912, + -0.2175520658493042, + 0.15988007187843323, + 0.013859080150723457 + ] + }, + { + "id": "/en/blue_gate_crossing", + "directed_by": [ + "Yee Chin-yen" + ], + "initial_release_date": "2002-09-08", + "name": "Blue Gate Crossing", + "genre": [ + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.1556316763162613, + -0.06180829927325249, + -0.2566208839416504, + 0.06211893633008003, + 0.3392902612686157, + -0.023724285885691643, + -0.20018546283245087, + -0.15106698870658875, + 0.05244278535246849, + -0.17319217324256897 + ] + }, + { + "id": "/en/blue_milk", + "directed_by": [ + "William Grammer" + ], + "initial_release_date": "2006-06-20", + "name": "Blue Milk", + "genre": [ + "Indie film", + "Short Film", + "Fan film" + ], + "film_vector": [ + -0.17981061339378357, + -0.01951524056494236, + -0.18171709775924683, + 0.1273280382156372, + 0.11267614364624023, + -0.3234257698059082, + -0.009953513741493225, + -0.1254645437002182, + 0.21589311957359314, + -0.08017532527446747 + ] + }, + { + "id": "/en/blue_state", + "directed_by": [ + "Marshall Lewy" + ], + "name": "Blue State", + "genre": [ + "Indie film", + "Romance Film", + "Political cinema", + "Romantic comedy", + "Political satire", + "Road movie", + "Comedy" + ], + "film_vector": [ + -0.35689839720726013, + 0.018472641706466675, + -0.4861527383327484, + 0.045215122401714325, + -0.09191282838582993, + -0.3192978501319885, + -0.05719207227230072, + -0.05345913767814636, + 0.06765596568584442, + -0.02124011144042015 + ] + }, + { + "id": "/en/blueberry_2004", + "directed_by": [ + "Jan Kounen" + ], + "initial_release_date": "2004-02-11", + "name": "Blueberry", + "genre": [ + "Western", + "Thriller", + "Action Film", + "Adventure Film" + ], + "film_vector": [ + -0.3558458387851715, + -0.1745622158050537, + -0.24001826345920563, + 0.2702178359031677, + 0.11230169236660004, + -0.23399528861045837, + -0.08304792642593384, + -0.18006011843681335, + -0.08355283737182617, + -0.16100887954235077 + ] + }, + { + "id": "/en/blueprint_2003", + "directed_by": [ + "Rolf Sch\u00fcbel" + ], + "initial_release_date": "2003-12-08", + "name": "Blueprint", + "genre": [ + "Science Fiction", + "Drama" + ], + "film_vector": [ + -0.23271621763706207, + -0.06810843199491501, + -0.02608516439795494, + -0.07691250741481781, + -0.09375110268592834, + 0.036815181374549866, + -0.09743650257587433, + -0.10641904175281525, + 0.024051645770668983, + -0.19779092073440552 + ] + }, + { + "id": "/en/bluffmaster", + "directed_by": [ + "Rohan Sippy" + ], + "initial_release_date": "2005-12-16", + "name": "Bluffmaster!", + "genre": [ + "Romance Film", + "Musical", + "Crime Fiction", + "Romantic comedy", + "Musical comedy", + "Comedy", + "Bollywood", + "World cinema", + "Drama", + "Musical Drama" + ], + "film_vector": [ + -0.5435199737548828, + 0.22594985365867615, + -0.2873753607273102, + 0.049766864627599716, + -0.01231073122471571, + -0.07543608546257019, + 0.09915798902511597, + 0.011270485818386078, + -0.11078737676143646, + -0.10354476422071457 + ] + }, + { + "id": "/en/boa_vs_python", + "directed_by": [ + "David Flores" + ], + "initial_release_date": "2004-05-24", + "name": "Boa vs. Python", + "genre": [ + "Horror", + "Natural horror film", + "Monster", + "Science Fiction", + "Creature Film" + ], + "film_vector": [ + -0.25755882263183594, + -0.1698407530784607, + 0.08624757826328278, + 0.24767640233039856, + -0.08421817421913147, + -0.1350870430469513, + 0.20436009764671326, + 0.16975553333759308, + 0.04607066139578819, + -0.016843674704432487 + ] + }, + { + "id": "/en/bobby", + "directed_by": [ + "Emilio Estevez" + ], + "initial_release_date": "2006-09-05", + "name": "Bobby", + "genre": [ + "Political drama", + "Historical period drama", + "History", + "Drama" + ], + "film_vector": [ + -0.07759162038564682, + 0.14507770538330078, + -0.17348864674568176, + -0.31627097725868225, + -0.1544302999973297, + -0.0711987316608429, + -0.15042582154273987, + 0.08066709339618683, + 0.007976345717906952, + -0.2804299592971802 + ] + }, + { + "id": "/en/boiler_room", + "directed_by": [ + "Ben Younger" + ], + "initial_release_date": "2000-01-30", + "name": "Boiler Room", + "genre": [ + "Crime Fiction", + "Drama" + ], + "film_vector": [ + -0.22757859528064728, + -0.16423380374908447, + -0.17972511053085327, + -0.2808937132358551, + 0.022973451763391495, + 0.08239687234163284, + 0.0528925321996212, + -0.16506129503250122, + 0.06357143819332123, + -0.33652517199516296 + ] + }, + { + "id": "/en/bolletjes_blues", + "directed_by": [ + "Brigit Hillenius", + "Karin Junger" + ], + "initial_release_date": "2006-03-23", + "name": "Bolletjes Blues", + "genre": [ + "Musical" + ], + "film_vector": [ + 0.14774398505687714, + 0.046717289835214615, + -0.17687994241714478, + -0.013379121199250221, + 0.09556636214256287, + -0.16811975836753845, + 0.02699700929224491, + 0.08728645741939545, + 0.04733343422412872, + -0.14004674553871155 + ] + }, + { + "id": "/en/bollywood_hollywood", + "directed_by": [ + "Deepa Mehta" + ], + "initial_release_date": "2002-10-25", + "name": "Bollywood/Hollywood", + "genre": [ + "Bollywood", + "Musical", + "Romance Film", + "Romantic comedy", + "Musical comedy", + "Comedy" + ], + "film_vector": [ + -0.5019495487213135, + 0.377105176448822, + -0.4420784115791321, + 0.07457087934017181, + 0.013752619735896587, + -0.12475462257862091, + 0.09043030440807343, + 0.08063095808029175, + -0.07624796032905579, + 0.03786539286375046 + ] + }, + { + "id": "/en/bomb_the_system", + "directed_by": [ + "Adam Bhala Lough" + ], + "name": "Bomb the System", + "genre": [ + "Crime Fiction", + "Indie film", + "Coming of age", + "Drama" + ], + "film_vector": [ + -0.4683261513710022, + -0.09212812781333923, + -0.27054548263549805, + -0.13973557949066162, + -0.20486001670360565, + -0.13232921063899994, + -0.025628747418522835, + -0.19054558873176575, + 0.24683226644992828, + -0.06463189423084259 + ] + }, + { + "id": "/en/bommarillu", + "directed_by": [ + "Bhaskar" + ], + "initial_release_date": "2006-08-09", + "name": "Bommarillu", + "genre": [ + "Musical", + "Romance Film", + "Drama", + "Musical Drama", + "Tollywood", + "World cinema" + ], + "film_vector": [ + -0.5687845945358276, + 0.3917340636253357, + -0.19759991765022278, + 0.028131624683737755, + -0.024865098297595978, + -0.12256545573472977, + 0.01692892611026764, + 0.07517733424901962, + 0.10618835687637329, + -0.05297081544995308 + ] + }, + { + "id": "/en/bon_cop_bad_cop", + "directed_by": [ + "Eric Canuel" + ], + "name": "Bon Cop, Bad Cop", + "genre": [ + "Crime Fiction", + "Buddy film", + "Action Film", + "Action/Adventure", + "Thriller", + "Comedy" + ], + "film_vector": [ + -0.48504096269607544, + -0.22912630438804626, + -0.4126184582710266, + 0.11411590129137039, + -0.13966041803359985, + -0.09050559997558594, + 0.040180474519729614, + -0.26227614283561707, + -0.078493133187294, + -0.17911416292190552 + ] + }, + { + "id": "/en/bones_2001", + "directed_by": [ + "Ernest R. Dickerson" + ], + "initial_release_date": "2001-10-26", + "name": "Bones", + "genre": [ + "Horror", + "Blaxploitation film", + "Action Film" + ], + "film_vector": [ + -0.43393799662590027, + -0.20865638554096222, + -0.03951076790690422, + 0.20448866486549377, + -0.009531201794743538, + -0.3092585504055023, + 0.1512155532836914, + -0.021645348519086838, + 0.05902727693319321, + -0.08937663584947586 + ] + }, + { + "id": "/en/bonjour_monsieur_shlomi", + "directed_by": [ + "Shemi Zarhin" + ], + "initial_release_date": "2003-04-03", + "name": "Bonjour Monsieur Shlomi", + "genre": [ + "World cinema", + "Family Drama", + "Comedy-drama", + "Coming of age", + "Family", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.3269050717353821, + 0.2798938453197479, + -0.24874985218048096, + -0.027466759085655212, + -0.12250526249408722, + -0.0866207480430603, + 0.028835363686084747, + -0.004112654365599155, + 0.2243797481060028, + -0.23553739488124847 + ] + }, + { + "id": "/en/boogeyman", + "directed_by": [ + "Stephen T. Kay" + ], + "initial_release_date": "2005-02-04", + "name": "Boogeyman", + "genre": [ + "Horror", + "Supernatural", + "Teen film", + "Thriller", + "Mystery", + "Drama" + ], + "film_vector": [ + -0.44850707054138184, + -0.39142584800720215, + -0.20167133212089539, + 0.1970689445734024, + -0.0037857545539736748, + -0.057864487171173096, + 0.15622732043266296, + -0.018842533230781555, + 0.1568247675895691, + -0.056668635457754135 + ] + }, + { + "id": "/en/boogiepop_and_others_2000", + "directed_by": [ + "Ryu Kaneda" + ], + "initial_release_date": "2000-03-11", + "name": "Boogiepop and Others", + "genre": [ + "Animation", + "Fantasy", + "Anime", + "Thriller", + "Japanese Movies" + ], + "film_vector": [ + -0.41691797971725464, + 0.0797836184501648, + 0.023214245215058327, + 0.3487473428249359, + -0.1689489334821701, + 0.049750082194805145, + 0.11682406067848206, + -0.09242433309555054, + 0.2513812780380249, + -0.11673247814178467 + ] + }, + { + "id": "/en/book_of_love_2004", + "directed_by": [ + "Alan Brown" + ], + "initial_release_date": "2004-01-18", + "name": "Book of Love", + "genre": [ + "Indie film", + "Romance Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.41115593910217285, + 0.07629252225160599, + -0.48086196184158325, + 0.10276895016431808, + 0.18317759037017822, + -0.1397908627986908, + -0.0875604897737503, + -0.07225452363491058, + 0.20530492067337036, + -0.17749229073524475 + ] + }, + { + "id": "/en/book_of_shadows_blair_witch_2", + "directed_by": [ + "Joe Berlinger" + ], + "initial_release_date": "2000-10-27", + "name": "Book of Shadows: Blair Witch 2", + "genre": [ + "Horror", + "Supernatural", + "Mystery", + "Psychological thriller", + "Slasher", + "Thriller", + "Ensemble Film", + "Crime Fiction" + ], + "film_vector": [ + -0.469166100025177, + -0.42411303520202637, + -0.15696439146995544, + 0.034434907138347626, + 0.05435743182897568, + -0.06094128638505936, + 0.08666815608739853, + 0.09747640788555145, + 0.07351931184530258, + -0.19577614963054657 + ] + }, + { + "id": "/en/boomer", + "directed_by": [ + "Pyotr Buslov" + ], + "initial_release_date": "2003-08-02", + "name": "Bimmer", + "genre": [ + "Crime Fiction", + "Drama" + ], + "film_vector": [ + -0.307567298412323, + -0.15570226311683655, + -0.14719650149345398, + -0.27846503257751465, + -0.1077766939997673, + 0.09717106074094772, + 0.018765490502119064, + -0.21245470643043518, + 0.006532927975058556, + -0.4084094762802124 + ] + }, + { + "id": "/wikipedia/de_id/1782985", + "directed_by": [ + "Larry Charles" + ], + "initial_release_date": "2006-08-04", + "name": "Borat: Cultural Learnings of America for Make Benefit Glorious Nation of Kazakhstan", + "genre": [ + "Comedy" + ], + "film_vector": [ + 0.019577985629439354, + 0.27673986554145813, + -0.09926356375217438, + 0.029806505888700485, + -0.14361800253391266, + -0.22529973089694977, + 0.2704688608646393, + -0.15801481902599335, + 0.007111745420843363, + -0.09577279537916183 + ] + }, + { + "id": "/en/born_into_brothels_calcuttas_red_light_kids", + "directed_by": [ + "Zana Briski", + "Ross Kauffman" + ], + "initial_release_date": "2004-01-17", + "name": "Born into Brothels: Calcutta's Red Light Kids", + "genre": [ + "Documentary film" + ], + "film_vector": [ + -0.03832671791315079, + 0.1729206144809723, + 0.046336155384778976, + -0.19647496938705444, + 0.05928681790828705, + -0.14166834950447083, + 0.1296204924583435, + -0.012003794312477112, + 0.20478403568267822, + -0.08547896146774292 + ] + }, + { + "id": "/en/free_radicals", + "directed_by": [ + "Barbara Albert" + ], + "name": "Free Radicals", + "genre": [ + "World cinema", + "Romance Film", + "Art film", + "Drama" + ], + "film_vector": [ + -0.3419019877910614, + 0.1810099184513092, + -0.016897795721888542, + -0.07845655083656311, + -0.08623083680868149, + -0.25527477264404297, + -0.05485345423221588, + -0.025973167270421982, + 0.29290536046028137, + -0.15974284708499908 + ] + }, + { + "id": "/en/boss_2006", + "directed_by": [ + "V.N. Aditya" + ], + "initial_release_date": "2006-09-27", + "name": "Boss", + "genre": [ + "Musical", + "Romance Film", + "Drama", + "Musical Drama", + "Tollywood", + "World cinema" + ], + "film_vector": [ + -0.5785576105117798, + 0.2878539562225342, + -0.27995193004608154, + 0.013860214501619339, + -0.06340112537145615, + -0.15422192215919495, + -0.03121565654873848, + 0.0706697404384613, + -0.007622473407536745, + -0.020880207419395447 + ] + }, + { + "id": "/en/bossn_up", + "directed_by": [ + "Dylan C. Brown" + ], + "initial_release_date": "2005-06-01", + "name": "Boss'n Up", + "genre": [ + "Musical", + "Indie film", + "Crime Fiction", + "Musical Drama", + "Drama" + ], + "film_vector": [ + -0.37503284215927124, + -0.02317143976688385, + -0.4382933974266052, + -0.02539503201842308, + -0.13399410247802734, + -0.1780296415090561, + -0.05587112531065941, + -0.043881651014089584, + 0.10188107192516327, + -0.019191253930330276 + ] + }, + { + "id": "/en/bossa_nova_2000", + "directed_by": [ + "Bruno Barreto" + ], + "initial_release_date": "2000-02-18", + "name": "Bossa Nova", + "genre": [ + "Romance Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.2829028367996216, + 0.07460428029298782, + -0.2687576413154602, + 0.0823601707816124, + 0.26867949962615967, + -0.1200866550207138, + -0.0318756140768528, + -0.041655197739601135, + 0.11755860596895218, + -0.10771627724170685 + ] + }, + { + "id": "/en/bosta", + "directed_by": [ + "Philippe Aractingi" + ], + "name": "Bosta", + "genre": [ + "Musical" + ], + "film_vector": [ + 0.035634465515613556, + 0.13393208384513855, + -0.17647504806518555, + -0.014127830043435097, + 0.07479916512966156, + -0.053583819419145584, + 0.029627595096826553, + 0.11145876348018646, + 0.1413024663925171, + -0.08137429505586624 + ] + }, + { + "id": "/en/bowling_for_columbine", + "directed_by": [ + "Michael Moore" + ], + "initial_release_date": "2002-05-15", + "name": "Bowling for Columbine", + "genre": [ + "Indie film", + "Documentary film", + "Political cinema", + "Historical Documentaries" + ], + "film_vector": [ + -0.34056538343429565, + -0.03711069002747536, + -0.24647068977355957, + 0.0009996667504310608, + -0.22015056014060974, + -0.43500369787216187, + -0.07960371673107147, + -0.18128952383995056, + 0.3053027391433716, + -0.023299822583794594 + ] + }, + { + "id": "/en/bowling_fun_and_fundamentals_for_boys_and_girls", + "directed_by": [], + "name": "Bowling Fun And Fundamentals For Boys And Girls", + "genre": [ + "Documentary film", + "Sports" + ], + "film_vector": [ + 0.06027064099907875, + 0.059556327760219574, + -0.0427011102437973, + 0.08505158871412277, + -0.1182611733675003, + -0.12580366432666779, + -0.06638559699058533, + -0.22551873326301575, + 0.05179823562502861, + 0.050298579037189484 + ] + }, + { + "id": "/en/boy_eats_girl", + "directed_by": [ + "Stephen Bradley" + ], + "initial_release_date": "2005-04-06", + "name": "Boy Eats Girl", + "genre": [ + "Indie film", + "Horror", + "Teen film", + "Creature Film", + "Zombie Film", + "Horror comedy", + "Comedy" + ], + "film_vector": [ + -0.36560243368148804, + -0.2436980903148651, + -0.35217416286468506, + 0.26323264837265015, + -0.029644478112459183, + -0.19604690372943878, + 0.13446055352687836, + 0.10553780943155289, + 0.21997705101966858, + 0.026765506714582443 + ] + }, + { + "id": "/en/boynton_beach_club", + "directed_by": [ + "Susan Seidelman" + ], + "initial_release_date": "2006-08-04", + "name": "Boynton Beach Club", + "genre": [ + "Romantic comedy", + "Indie film", + "Romance Film", + "Comedy-drama", + "Slice of life", + "Ensemble Film", + "Comedy" + ], + "film_vector": [ + -0.24145770072937012, + -0.038841187953948975, + -0.5561990737915039, + 0.13825714588165283, + 0.025356154888868332, + -0.16726331412792206, + -0.11681710928678513, + -0.06066955626010895, + 0.10564383864402771, + -0.008611352182924747 + ] + }, + { + "id": "/en/boys_2003", + "directed_by": [ + "S. Shankar" + ], + "initial_release_date": "2003-08-29", + "name": "Boys", + "genre": [ + "Musical", + "Romance Film", + "Comedy", + "Tamil cinema", + "World cinema", + "Drama", + "Musical comedy", + "Musical Drama" + ], + "film_vector": [ + -0.5734235048294067, + 0.3980081081390381, + -0.3274621069431305, + 0.07621592283248901, + -0.09083187580108643, + -0.10739003121852875, + 0.012629193253815174, + 0.08868566155433655, + 0.02328728325664997, + 0.028561335057020187 + ] + }, + { + "id": "/en/brain_blockers", + "directed_by": [ + "Lincoln Kupchak" + ], + "initial_release_date": "2007-03-15", + "name": "Brain Blockers", + "genre": [ + "Horror", + "Zombie Film", + "Horror comedy", + "Comedy" + ], + "film_vector": [ + -0.24522411823272705, + -0.29151320457458496, + -0.2543156147003174, + 0.18064314126968384, + -0.09815506637096405, + -0.185063436627388, + 0.2832477390766144, + 0.06982049345970154, + 0.12518011033535004, + -0.04411766305565834 + ] + }, + { + "id": "/en/breakin_all_the_rules", + "directed_by": [ + "Daniel Taplitz" + ], + "initial_release_date": "2004-05-14", + "name": "Breakin' All the Rules", + "genre": [ + "Romance Film", + "Romantic comedy", + "Comedy of Errors", + "Comedy" + ], + "film_vector": [ + -0.1397070288658142, + 0.07988511025905609, + -0.5672355890274048, + 0.05812181532382965, + 0.11908130347728729, + -0.18040089309215546, + 0.013413748703897, + 0.013804859481751919, + -0.04139524698257446, + -0.0872240960597992 + ] + }, + { + "id": "/en/breaking_and_entering", + "directed_by": [ + "Anthony Minghella" + ], + "initial_release_date": "2006-09-13", + "name": "Breaking and Entering", + "genre": [ + "Romance Film", + "Crime Fiction", + "Drama" + ], + "film_vector": [ + -0.4429689645767212, + -0.16741900146007538, + -0.30163466930389404, + -0.10472401231527328, + 0.06357046216726303, + -0.029791535809636116, + -0.031088124960660934, + -0.20226603746414185, + 0.09638403356075287, + -0.23167870938777924 + ] + }, + { + "id": "/en/brick_2006", + "directed_by": [ + "Rian Johnson" + ], + "initial_release_date": "2006-04-07", + "name": "Brick", + "genre": [ + "Film noir", + "Indie film", + "Teen film", + "Neo-noir", + "Mystery", + "Crime Thriller", + "Crime Fiction", + "Thriller", + "Detective fiction", + "Drama" + ], + "film_vector": [ + -0.5925610065460205, + -0.24066729843616486, + -0.41286706924438477, + -0.11015164107084274, + -0.1802566796541214, + -0.1571086198091507, + -0.04412068426609039, + 0.0033947299234569073, + 0.09404143691062927, + -0.08264676481485367 + ] + }, + { + "id": "/en/bride_and_prejudice", + "directed_by": [ + "Gurinder Chadha" + ], + "initial_release_date": "2004-10-06", + "name": "Bride and Prejudice", + "genre": [ + "Musical", + "Romantic comedy", + "Romance Film", + "Film adaptation", + "Comedy of manners", + "Musical Drama", + "Musical comedy", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.28883200883865356, + 0.14737620949745178, + -0.580416202545166, + 0.005596227943897247, + -0.0062387664802372456, + -0.1999828964471817, + -0.10455787926912308, + 0.317324161529541, + -0.1583748757839203, + -0.09314252436161041 + ] + }, + { + "id": "/en/bridget_jones_the_edge_of_reason", + "directed_by": [ + "Beeban Kidron" + ], + "initial_release_date": "2004-11-08", + "name": "Bridget Jones: The Edge of Reason", + "genre": [ + "Romantic comedy", + "Romance Film", + "Comedy" + ], + "film_vector": [ + -0.22045063972473145, + -0.005079228430986404, + -0.40283700823783875, + 0.06473765522241592, + 0.25639232993125916, + -0.16883954405784607, + -0.1628645658493042, + -0.0008983202278614044, + 0.03643545135855675, + -0.1870701014995575 + ] + }, + { + "id": "/en/bridget_joness_diary_2001", + "directed_by": [ + "Sharon Maguire" + ], + "initial_release_date": "2001-04-04", + "name": "Bridget Jones's Diary", + "genre": [ + "Romantic comedy", + "Film adaptation", + "Romance Film", + "Comedy of manners", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.2721511125564575, + 0.028474371880292892, + -0.47797611355781555, + 0.01207922026515007, + 0.12733951210975647, + -0.17401675879955292, + -0.15845289826393127, + 0.1314963400363922, + -0.0712042823433876, + -0.16106173396110535 + ] + }, + { + "id": "/en/brigham_city_2001", + "directed_by": [ + "Richard Dutcher" + ], + "name": "Brigham City", + "genre": [ + "Mystery", + "Indie film", + "Crime Fiction", + "Thriller", + "Crime Thriller", + "Drama" + ], + "film_vector": [ + -0.42329734563827515, + -0.3063125014305115, + -0.28268951177597046, + -0.0576903335750103, + 0.00012222211807966232, + -0.11000127345323563, + -0.05820123851299286, + -0.1274586319923401, + 0.11399109661579132, + -0.15321886539459229 + ] + }, + { + "id": "/en/bright_young_things", + "directed_by": [ + "Stephen Fry" + ], + "initial_release_date": "2003-10-03", + "name": "Bright Young Things", + "genre": [ + "Indie film", + "War film", + "Comedy-drama", + "Historical period drama", + "Comedy of manners", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.3343506455421448, + 0.0986386388540268, + -0.44511616230010986, + 0.028942206874489784, + -0.1743451952934265, + -0.18056100606918335, + -0.08562001585960388, + 0.03098052740097046, + 0.16640517115592957, + -0.1913546919822693 + ] + }, + { + "id": "/wikipedia/en_title/Brilliant_$0028film$0029", + "directed_by": [ + "Roger Cardinal" + ], + "initial_release_date": "2004-02-15", + "name": "Brilliant", + "genre": [ + "Thriller" + ], + "film_vector": [ + -0.18825678527355194, + -0.32110220193862915, + -0.02311502769589424, + -0.19306793808937073, + 0.2188386619091034, + 0.009488238953053951, + 0.1324654519557953, + 0.0011986792087554932, + 0.05569251626729965, + -0.027894936501979828 + ] + }, + { + "id": "/en/bring_it_on", + "directed_by": [ + "Peyton Reed" + ], + "initial_release_date": "2000-08-22", + "name": "Bring It On", + "genre": [ + "Comedy", + "Sports" + ], + "film_vector": [ + 0.08178609609603882, + 0.13364523649215698, + -0.1972215473651886, + -0.1108008325099945, + -0.39010441303253174, + 0.03436852991580963, + 0.0992862731218338, + -0.17168006300926208, + -0.010646529495716095, + 0.1224927008152008 + ] + }, + { + "id": "/en/bring_it_on_again", + "directed_by": [ + "Damon Santostefano" + ], + "initial_release_date": "2004-01-13", + "name": "Bring It On Again", + "genre": [ + "Teen film", + "Sports", + "Comedy" + ], + "film_vector": [ + -0.10686258971691132, + 0.026412740349769592, + -0.32144469022750854, + 0.09742545336484909, + -0.22809761762619019, + -0.045216646045446396, + -0.06283679604530334, + -0.2581719160079956, + 0.20037178695201874, + 0.11414451897144318 + ] + }, + { + "id": "/en/bring_it_on_all_or_nothing", + "directed_by": [ + "Steve Rash" + ], + "initial_release_date": "2006-08-08", + "name": "Bring It On: All or Nothing", + "genre": [ + "Teen film", + "Sports", + "Comedy" + ], + "film_vector": [ + -0.006693275645375252, + 0.01467725820839405, + -0.3363072872161865, + 0.035253364592790604, + -0.1549321711063385, + -0.04894646629691124, + -0.06889957934617996, + -0.28564170002937317, + 0.21792076528072357, + 0.11277683079242706 + ] + }, + { + "id": "/en/bringing_down_the_house", + "directed_by": [ + "Adam Shankman" + ], + "initial_release_date": "2003-03-07", + "name": "Bringing Down the House", + "genre": [ + "Romantic comedy", + "Screwball comedy", + "Comedy of Errors", + "Crime Comedy", + "Comedy" + ], + "film_vector": [ + -0.21329250931739807, + -0.0331469289958477, + -0.5888321399688721, + -0.018468623980879784, + -0.153295636177063, + -0.18133793771266937, + 0.1971016526222229, + 0.04559028893709183, + -0.002952937036752701, + -0.16836440563201904 + ] + }, + { + "id": "/en/broadway_the_golden_age", + "directed_by": [ + "Rick McKay" + ], + "initial_release_date": "2004-06-11", + "name": "Broadway: The Golden Age", + "genre": [ + "Documentary film", + "Biographical film" + ], + "film_vector": [ + 0.002014413010329008, + 0.21251311898231506, + -0.16094213724136353, + -0.15030834078788757, + -0.07094652950763702, + -0.3099827766418457, + -0.22080469131469727, + 0.08601197600364685, + 0.12337265908718109, + -0.25400495529174805 + ] + }, + { + "id": "/en/brokeback_mountain", + "directed_by": [ + "Ang Lee" + ], + "initial_release_date": "2005-09-02", + "name": "Brokeback Mountain", + "genre": [ + "Romance Film", + "Epic film", + "Drama" + ], + "film_vector": [ + -0.24651455879211426, + -0.014726176857948303, + -0.44200965762138367, + 0.08391668647527695, + 0.0704602599143982, + -0.16750332713127136, + -0.21390250325202942, + -0.09456460177898407, + 0.06575316190719604, + -0.01425763126462698 + ] + }, + { + "id": "/en/broken_allegiance", + "directed_by": [ + "Nick Hallam" + ], + "name": "Broken Allegiance", + "genre": [ + "Indie film", + "Short Film", + "Fan film" + ], + "film_vector": [ + -0.1594168096780777, + -0.025686562061309814, + -0.14569905400276184, + 0.056894347071647644, + 0.16262602806091309, + -0.3644215166568756, + -0.12896305322647095, + -0.14400608837604523, + 0.19668935239315033, + -0.06212018430233002 + ] + }, + { + "id": "/en/broken_flowers", + "directed_by": [ + "Jim Jarmusch" + ], + "initial_release_date": "2005-08-05", + "name": "Broken Flowers", + "genre": [ + "Mystery", + "Road movie", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.23534473776817322, + -0.11430424451828003, + -0.4026479721069336, + 0.052587442100048065, + 0.112031489610672, + -0.15005004405975342, + 0.0012072070967406034, + -0.07285020500421524, + 0.16434651613235474, + -0.17654889822006226 + ] + }, + { + "id": "/en/the_broken_hearts_club_a_romantic_comedy", + "directed_by": [ + "Greg Berlanti" + ], + "initial_release_date": "2000-01-29", + "name": "The Broken Hearts Club: A Romantic Comedy", + "genre": [ + "Romance Film", + "LGBT", + "Romantic comedy", + "Gay Themed", + "Indie film", + "Comedy-drama", + "Gay", + "Gay Interest", + "Ensemble Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.13212038576602936, + -0.006576403975486755, + -0.42298346757888794, + -0.010635614395141602, + 0.17073260247707367, + -0.10143270343542099, + -0.1476079374551773, + 0.07466626167297363, + 0.03348418325185776, + -0.05765146389603615 + ] + }, + { + "id": "/en/brooklyn_lobster", + "directed_by": [ + "Kevin Jordan" + ], + "initial_release_date": "2005-09-09", + "name": "Brooklyn Lobster", + "genre": [ + "Indie film", + "Family Drama", + "Comedy-drama", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.17017266154289246, + -0.07172904163599014, + -0.47734591364860535, + 0.09817269444465637, + -0.10120391845703125, + -0.21921031177043915, + 0.015444034710526466, + 0.005734918639063835, + 0.10823434591293335, + -0.06328657269477844 + ] + }, + { + "id": "/en/brother", + "directed_by": [ + "Takeshi Kitano" + ], + "name": "Brother", + "genre": [ + "Thriller", + "Crime Fiction" + ], + "film_vector": [ + -0.2463858425617218, + -0.35665053129196167, + -0.1720218062400818, + -0.17828013002872467, + 0.04023047536611557, + 0.09146642684936523, + 0.04820965230464935, + -0.20693162083625793, + -0.014121653512120247, + -0.2471121996641159 + ] + }, + { + "id": "/en/brother_bear", + "directed_by": [ + "Aaron Blaise", + "Robert A. Walker" + ], + "initial_release_date": "2003-10-20", + "name": "Brother Bear", + "genre": [ + "Family", + "Fantasy", + "Animation", + "Adventure Film" + ], + "film_vector": [ + 0.0642523318529129, + 0.015553131699562073, + 0.03924836590886116, + 0.4365476369857788, + -0.03217896819114685, + -0.0006351331248879433, + -0.09051856398582458, + -0.10397343337535858, + 0.008992845192551613, + -0.2660965621471405 + ] + }, + { + "id": "/en/brother_bear_2", + "directed_by": [ + "Ben Gluck" + ], + "initial_release_date": "2006-08-29", + "name": "Brother Bear 2", + "genre": [ + "Family", + "Animated cartoon", + "Fantasy", + "Adventure Film", + "Animation" + ], + "film_vector": [ + 0.03651725500822067, + 0.029951587319374084, + -0.019668344408273697, + 0.51146399974823, + -0.11611732840538025, + -0.016774635761976242, + -0.09804649651050568, + -0.0675164982676506, + -0.00862671248614788, + -0.1966620236635208 + ] + }, + { + "id": "/en/brother_2", + "directed_by": [ + "Aleksei Balabanov" + ], + "initial_release_date": "2000-05-11", + "name": "Brother 2", + "genre": [ + "Crime Fiction", + "Thriller", + "Action Film" + ], + "film_vector": [ + -0.28832364082336426, + -0.28949111700057983, + -0.17587696015834808, + 0.0621902272105217, + 0.16253052651882172, + -0.06298884749412537, + -0.014825716614723206, + -0.3005194365978241, + -0.07606266438961029, + -0.15802229940891266 + ] + }, + { + "id": "/en/brotherhood_of_blood", + "directed_by": [ + "Michael Roesch", + "Peter Scheerer", + "Sid Haig" + ], + "name": "Brotherhood of Blood", + "genre": [ + "Horror", + "Cult film", + "Creature Film" + ], + "film_vector": [ + -0.29218149185180664, + -0.2930912375450134, + 0.011447999626398087, + 0.19287918508052826, + 0.07807423174381256, + -0.23416349291801453, + 0.16069456934928894, + 0.12208334356546402, + 0.14974352717399597, + -0.1512334644794464 + ] + }, + { + "id": "/en/brotherhood_of_the_wolf", + "directed_by": [ + "Christophe Gans" + ], + "initial_release_date": "2001-01-31", + "name": "Brotherhood of the Wolf", + "genre": [ + "Martial Arts Film", + "Adventure Film", + "Mystery", + "Science Fiction", + "Historical fiction", + "Thriller", + "Action Film" + ], + "film_vector": [ + -0.4383106231689453, + -0.23306819796562195, + -0.00898057222366333, + 0.2083435207605362, + 4.545971751213074e-05, + -0.1767553836107254, + -0.13221308588981628, + -0.005110093392431736, + -0.053147606551647186, + -0.1416996568441391 + ] + }, + { + "id": "/en/brothers_of_the_head", + "directed_by": [ + "Keith Fulton", + "Louis Pepe" + ], + "initial_release_date": "2005-09-10", + "name": "Brothers of the Head", + "genre": [ + "Indie film", + "Musical", + "Film adaptation", + "Music", + "Mockumentary", + "Comedy-drama", + "Historical period drama", + "Musical Drama", + "Drama" + ], + "film_vector": [ + -0.141446053981781, + 0.015508811920881271, + -0.34839296340942383, + -0.03530041500926018, + -0.11371740698814392, + -0.2834983766078949, + -0.071867436170578, + 0.26357775926589966, + 0.00043001770973205566, + -0.08840855956077576 + ] + }, + { + "id": "/en/brown_sugar_2002", + "directed_by": [ + "Rick Famuyiwa" + ], + "initial_release_date": "2002-10-05", + "name": "Brown Sugar", + "genre": [ + "Musical", + "Romantic comedy", + "Coming of age", + "Romance Film", + "Musical Drama", + "Musical comedy", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.27596303820610046, + 0.05696789175271988, + -0.6310858130455017, + 0.016779722645878792, + -0.05524730682373047, + -0.1184462457895279, + -0.1626981645822525, + 0.18992392718791962, + 0.04537405073642731, + -0.011875084601342678 + ] + }, + { + "id": "/en/bruce_almighty", + "directed_by": [ + "Tom Shadyac" + ], + "initial_release_date": "2003-05-23", + "name": "Bruce Almighty", + "genre": [ + "Comedy", + "Fantasy", + "Drama" + ], + "film_vector": [ + -0.28174182772636414, + -0.052030473947525024, + -0.24316224455833435, + 0.2659239172935486, + -0.14625398814678192, + -0.1021481454372406, + -0.04195728898048401, + -0.11428070068359375, + -0.07440973818302155, + -0.15957997739315033 + ] + }, + { + "id": "/en/bubba_ho-tep", + "directed_by": [ + "Don Coscarelli" + ], + "initial_release_date": "2002-06-09", + "name": "Bubba Ho-Tep", + "genre": [ + "Horror", + "Parody", + "Comedy", + "Mystery", + "Drama" + ], + "film_vector": [ + -0.11444458365440369, + -0.14393767714500427, + -0.3390582501888275, + 0.18132928013801575, + -0.21356934309005737, + -0.10575883835554123, + 0.2044306993484497, + -0.09128958731889725, + -0.011359333992004395, + -0.2045680582523346 + ] + }, + { + "id": "/en/bubble", + "directed_by": [ + "Steven Soderbergh" + ], + "initial_release_date": "2005-09-03", + "name": "Bubble", + "genre": [ + "Crime Fiction", + "Mystery", + "Indie film", + "Thriller", + "Drama" + ], + "film_vector": [ + -0.5332342386245728, + -0.2747948169708252, + -0.30300289392471313, + -0.048984743654727936, + -0.11899306625127792, + -0.0372781977057457, + 0.03773709386587143, + -0.18946027755737305, + 0.13591861724853516, + -0.15651647746562958 + ] + }, + { + "id": "/en/bubble_boy", + "directed_by": [ + "Blair Hayes" + ], + "initial_release_date": "2001-08-23", + "name": "Bubble Boy", + "genre": [ + "Romance Film", + "Teen film", + "Romantic comedy", + "Adventure Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.3898451328277588, + 0.07506556808948517, + -0.49658018350601196, + 0.28733354806900024, + 0.028922274708747864, + -0.08835798501968384, + -0.14354196190834045, + -0.047377992421388626, + 0.04165158420801163, + -0.015128405764698982 + ] + }, + { + "id": "/en/buddy_boy", + "directed_by": [ + "Mark Hanlon" + ], + "initial_release_date": "2000-03-24", + "name": "Buddy Boy", + "genre": [ + "Psychological thriller", + "Thriller", + "Indie film", + "Erotic thriller" + ], + "film_vector": [ + -0.30514246225357056, + -0.21227329969406128, + -0.4655926525592804, + 0.11996939778327942, + 0.20688602328300476, + -0.12116971611976624, + 0.030755899846553802, + -0.14407268166542053, + 0.11330638825893402, + -0.05645405501127243 + ] + }, + { + "id": "/en/buffalo_dreams", + "directed_by": [ + "David Jackson" + ], + "initial_release_date": "2005-03-11", + "name": "Buffalo Dreams", + "genre": [ + "Western", + "Teen film", + "Drama" + ], + "film_vector": [ + -0.08816753327846527, + -0.06301842629909515, + -0.19841063022613525, + 0.18699908256530762, + 0.08932428807020187, + -0.2001791149377823, + -0.1742907464504242, + -0.23668012022972107, + 0.025534924119710922, + -0.20884664356708527 + ] + }, + { + "id": "/en/buffalo_soldiers", + "directed_by": [ + "Gregor Jordan" + ], + "initial_release_date": "2001-09-08", + "name": "Buffalo Soldiers", + "genre": [ + "War film", + "Crime Fiction", + "Comedy", + "Thriller", + "Satire", + "Indie film", + "Drama" + ], + "film_vector": [ + -0.278480589389801, + -0.0965118557214737, + -0.24082493782043457, + 0.013581089675426483, + -0.2125832736492157, + -0.31757640838623047, + -0.12049101293087006, + -0.11369505524635315, + -0.004709754139184952, + -0.2329872101545334 + ] + }, + { + "id": "/en/bug_2006", + "directed_by": [ + "William Friedkin" + ], + "initial_release_date": "2006-05-19", + "name": "Bug", + "genre": [ + "Thriller", + "Horror", + "Indie film", + "Drama" + ], + "film_vector": [ + -0.49374037981033325, + -0.24663816392421722, + -0.22024911642074585, + 0.13755476474761963, + 0.0391133688390255, + -0.1563546359539032, + 0.08661923557519913, + -0.008000240661203861, + 0.1949540674686432, + -0.06474762409925461 + ] + }, + { + "id": "/en/bulletproof_monk", + "directed_by": [ + "Paul Hunter" + ], + "initial_release_date": "2003-04-16", + "name": "Bulletproof Monk", + "genre": [ + "Martial Arts Film", + "Fantasy", + "Action Film", + "Buddy film", + "Thriller", + "Action/Adventure", + "Action Comedy", + "Comedy" + ], + "film_vector": [ + -0.39872148633003235, + -0.08151072263717651, + -0.27663910388946533, + 0.2951383590698242, + -0.03895806521177292, + -0.24135395884513855, + -0.0017250943928956985, + -0.1273694783449173, + -0.13297903537750244, + -0.05229014903306961 + ] + }, + { + "id": "/en/bully_2001", + "directed_by": [ + "Larry Clark" + ], + "initial_release_date": "2001-06-15", + "name": "Bully", + "genre": [ + "Teen film", + "Crime Fiction", + "Thriller", + "Drama" + ], + "film_vector": [ + -0.3176279664039612, + -0.2535960078239441, + -0.298667311668396, + 0.044883809983730316, + 0.06732161343097687, + -0.05857904255390167, + -0.025961965322494507, + -0.2206306755542755, + 0.11321014165878296, + -0.09938640892505646 + ] + }, + { + "id": "/en/bunny_2005", + "directed_by": [ + "V. V. Vinayak" + ], + "initial_release_date": "2005-04-06", + "name": "Bunny", + "genre": [ + "Musical", + "Romance Film", + "World cinema", + "Tollywood", + "Musical Drama", + "Drama" + ], + "film_vector": [ + -0.4314331114292145, + 0.30401721596717834, + -0.3005857467651367, + 0.16808924078941345, + -0.06822432577610016, + -0.06589891761541367, + -0.02788599207997322, + 0.0452762171626091, + 0.17076468467712402, + -0.12207502871751785 + ] + }, + { + "id": "/en/bunshinsaba", + "directed_by": [ + "Ahn Byeong-ki" + ], + "initial_release_date": "2004-05-14", + "name": "Bunshinsaba", + "genre": [ + "Horror", + "World cinema", + "East Asian cinema" + ], + "film_vector": [ + -0.43895435333251953, + 0.046330757439136505, + 0.03995092958211899, + 0.14147478342056274, + -0.08616246283054352, + -0.1788564920425415, + 0.17167869210243225, + 0.06491713225841522, + 0.27111315727233887, + -0.2779088616371155 + ] + }, + { + "id": "/en/bunty_aur_babli", + "directed_by": [ + "Shaad Ali" + ], + "initial_release_date": "2005-05-27", + "name": "Bunty Aur Babli", + "genre": [ + "Romance Film", + "Musical", + "World cinema", + "Musical comedy", + "Comedy", + "Adventure Film", + "Crime Fiction" + ], + "film_vector": [ + -0.4436904788017273, + 0.2906093895435333, + -0.23472195863723755, + 0.100192591547966, + -0.02091880515217781, + -0.14399270713329315, + 0.0744221955537796, + 0.003095338586717844, + 0.08077991753816605, + -0.23309344053268433 + ] + }, + { + "id": "/en/onibus_174", + "directed_by": [ + "Jos\u00e9 Padilha" + ], + "initial_release_date": "2002-10-22", + "name": "Bus 174", + "genre": [ + "Documentary film", + "True crime" + ], + "film_vector": [ + 0.01303572952747345, + -0.07245704531669617, + 0.01854834146797657, + -0.22956982254981995, + 0.12301227450370789, + -0.3251701891422272, + -0.015633583068847656, + -0.15620973706245422, + 0.06406752020120621, + -0.07427435368299484 + ] + }, + { + "id": "/en/bus_conductor", + "directed_by": [ + "V. M. Vinu" + ], + "initial_release_date": "2005-12-23", + "name": "Bus Conductor", + "genre": [ + "Comedy", + "Action Film", + "Malayalam Cinema", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.482695996761322, + 0.40011516213417053, + -0.0836254358291626, + 0.015803243964910507, + -0.035610754042863846, + -0.17694203555583954, + 0.16792134940624237, + -0.09044893831014633, + -0.07436297088861465, + -0.07930724322795868 + ] + }, + { + "id": "/m/0bvs38", + "directed_by": [ + "Michael Votto" + ], + "name": "Busted Shoes and Broken Hearts: A Film About Lowlight", + "genre": [ + "Indie film", + "Documentary film" + ], + "film_vector": [ + -0.07375118136405945, + -0.0481986366212368, + -0.206429123878479, + -0.08477385342121124, + 0.040890708565711975, + -0.41884034872055054, + -0.03224308043718338, + -0.12458012998104095, + 0.28326913714408875, + -0.05262766778469086 + ] + }, + { + "id": "/en/butterfly_2004", + "directed_by": [ + "Yan Yan Mak" + ], + "initial_release_date": "2004-09-04", + "name": "Butterfly", + "genre": [ + "LGBT", + "Chinese Movies", + "Drama" + ], + "film_vector": [ + -0.22181496024131775, + 0.19181013107299805, + -0.19048810005187988, + 0.011634872294962406, + -0.038532424718141556, + 0.0016898885369300842, + -0.09755872189998627, + -0.027328049764037132, + 0.3353962302207947, + -0.17345188558101654 + ] + }, + { + "id": "/en/butterfly_on_a_wheel", + "directed_by": [ + "Mike Barker" + ], + "initial_release_date": "2007-02-10", + "name": "Butterfly on a Wheel", + "genre": [ + "Thriller", + "Crime Thriller", + "Crime Fiction", + "Psychological thriller", + "Drama" + ], + "film_vector": [ + -0.5208566784858704, + -0.26924410462379456, + -0.3502432107925415, + -0.1287124752998352, + -0.11275415122509003, + -0.0005751196295022964, + -0.057116299867630005, + 0.036619458347558975, + 0.037665486335754395, + -0.05275953933596611 + ] + }, + { + "id": "/en/c_i_d_moosa", + "directed_by": [ + "Johny Antony" + ], + "initial_release_date": "2003-07-04", + "name": "C.I.D.Moosa", + "genre": [ + "Action Film", + "Comedy", + "Malayalam Cinema", + "World cinema" + ], + "film_vector": [ + -0.4750925600528717, + 0.35236358642578125, + 0.025261998176574707, + 0.11621037125587463, + 0.03917588293552399, + -0.1880674958229065, + 0.19016574323177338, + -0.13639362156391144, + -0.017905469983816147, + -0.030310234054923058 + ] + }, + { + "id": "/en/c_r_a_z_y", + "directed_by": [ + "Jean-Marc Vall\u00e9e" + ], + "initial_release_date": "2005-05-27", + "name": "C.R.A.Z.Y.", + "genre": [ + "LGBT", + "Indie film", + "Comedy-drama", + "Gay", + "Gay Interest", + "Gay Themed", + "Historical period drama", + "Coming of age", + "Drama" + ], + "film_vector": [ + -0.30293112993240356, + 0.10274340212345123, + -0.4273250997066498, + -0.019991060718894005, + -0.16537931561470032, + -0.09019646048545837, + -0.15803760290145874, + 0.04611409828066826, + 0.214758962392807, + -0.1385585367679596 + ] + }, + { + "id": "/en/c_s_a_the_confederate_states_of_america", + "directed_by": [ + "Kevin Willmott" + ], + "name": "C.S.A.: The Confederate States of America", + "genre": [ + "Mockumentary", + "Satire", + "Black comedy", + "Parody", + "Indie film", + "Political cinema", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.024134181439876556, + -0.004284888505935669, + -0.2968211770057678, + -0.11555740237236023, + -0.18570658564567566, + -0.35665363073349, + 0.044302813708782196, + -0.005970134399831295, + 0.0035796016454696655, + -0.15661782026290894 + ] + }, + { + "id": "/en/cabaret_paradis", + "directed_by": [ + "Corinne Benizio", + "Gilles Benizio" + ], + "initial_release_date": "2006-04-12", + "name": "Cabaret Paradis", + "genre": [ + "Comedy" + ], + "film_vector": [ + 0.07412685453891754, + 0.0890064686536789, + -0.3116266131401062, + -0.057175517082214355, + 0.0862160250544548, + -0.14166025817394257, + 0.19420583546161652, + 0.06402207165956497, + 0.06994062662124634, + -0.22204235196113586 + ] + }, + { + "id": "/wikipedia/it_id/335645", + "directed_by": [ + "Michael Haneke" + ], + "initial_release_date": "2005-05-14", + "name": "Cach\u00e9", + "genre": [ + "Thriller", + "Mystery", + "Psychological thriller", + "Drama" + ], + "film_vector": [ + -0.5590595006942749, + -0.30736884474754333, + -0.30265024304389954, + -0.1525888890028, + -0.01785762421786785, + -0.030681408941745758, + 0.013841754756867886, + 0.02214484103024006, + -0.0010980144143104553, + -0.08590412139892578 + ] + }, + { + "id": "/en/cactuses", + "directed_by": [ + "Matt Hannon", + "Rick Rapoza" + ], + "initial_release_date": "2006-03-15", + "name": "Cactuses", + "genre": [ + "Drama" + ], + "film_vector": [ + 0.14421877264976501, + -0.010733257979154587, + -0.0738496482372284, + -0.11232201009988785, + 0.007482840679585934, + 0.19655555486679077, + -0.031660810112953186, + 0.13324525952339172, + -0.03821707144379616, + 0.08988906443119049 + ] + }, + { + "id": "/en/cadet_kelly", + "directed_by": [ + "Larry Shaw" + ], + "initial_release_date": "2002-03-08", + "name": "Cadet Kelly", + "genre": [ + "Teen film", + "Coming of age", + "Family", + "Comedy" + ], + "film_vector": [ + 0.002283245325088501, + -0.10084615647792816, + -0.3183170258998871, + 0.17139601707458496, + 0.20996469259262085, + -0.14698472619056702, + -0.08361229300498962, + -0.246416836977005, + 0.029813969507813454, + -0.15967567265033722 + ] + }, + { + "id": "/en/caffeine_2006", + "directed_by": [ + "John Cosgrove" + ], + "name": "Caffeine", + "genre": [ + "Romantic comedy", + "Romance Film", + "Indie film", + "Ensemble Film", + "Workplace Comedy", + "Comedy" + ], + "film_vector": [ + -0.33582866191864014, + 0.002134159207344055, + -0.5715432167053223, + 0.0854438915848732, + 0.038717225193977356, + -0.18223422765731812, + 0.02302231267094612, + -0.06521885097026825, + 0.07664524018764496, + -0.05318870022892952 + ] + }, + { + "id": "/wikipedia/es_id/1062610", + "directed_by": [ + "Nisha Ganatra", + "Jennifer Arzt" + ], + "name": "Cake", + "genre": [ + "Romantic comedy", + "Short Film", + "Romance Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.26158106327056885, + 0.09374597668647766, + -0.5306806564331055, + 0.11315286159515381, + 0.12495310604572296, + -0.13170671463012695, + 0.010165078565478325, + 0.03390609845519066, + 0.09536328911781311, + -0.11011925339698792 + ] + }, + { + "id": "/en/calcutta_mail", + "directed_by": [ + "Sudhir Mishra" + ], + "initial_release_date": "2003-06-30", + "name": "Calcutta Mail", + "genre": [ + "Thriller", + "Bollywood", + "World cinema" + ], + "film_vector": [ + -0.5387915372848511, + 0.19011113047599792, + -0.04962035268545151, + -0.08324666321277618, + 0.06200111657381058, + -0.10303635895252228, + 0.24811773002147675, + -0.147052600979805, + -0.018055791035294533, + -0.11006954312324524 + ] + }, + { + "id": "/en/can_you_hack_it", + "directed_by": [ + "Sam Bozzo" + ], + "name": "Hackers Wanted", + "genre": [ + "Indie film", + "Documentary film" + ], + "film_vector": [ + -0.18403340876102448, + -0.07383424043655396, + 0.028491739183664322, + 0.013098286464810371, + 0.03045053593814373, + -0.3389075994491577, + 0.040329571813344955, + -0.255609929561615, + 0.20398882031440735, + 0.024895841255784035 + ] + }, + { + "id": "/en/candy_2006", + "directed_by": [ + "Neil Armfield" + ], + "initial_release_date": "2006-04-27", + "name": "Candy", + "genre": [ + "Romance Film", + "Indie film", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.4679781198501587, + 0.1175934374332428, + -0.33119410276412964, + 0.06340471655130386, + 0.06038089096546173, + -0.16770054399967194, + -0.03106105513870716, + -0.06607553362846375, + 0.31143417954444885, + -0.11406965553760529 + ] + }, + { + "id": "/en/caotica_ana", + "directed_by": [ + "Julio Medem" + ], + "initial_release_date": "2007-08-24", + "name": "Ca\u00f3tica Ana", + "genre": [ + "Romance Film", + "Mystery", + "Drama" + ], + "film_vector": [ + -0.32190337777137756, + 0.13740989565849304, + -0.12430466711521149, + 0.029530098661780357, + 0.3560066819190979, + -0.012383285909891129, + 0.024244965985417366, + -0.04585377126932144, + 0.12164698541164398, + -0.22505897283554077 + ] + }, + { + "id": "/en/capote", + "directed_by": [ + "Bennett Miller" + ], + "initial_release_date": "2005-09-02", + "name": "Capote", + "genre": [ + "Crime Fiction", + "Biographical film", + "Drama" + ], + "film_vector": [ + -0.263824999332428, + -0.13657602667808533, + -0.17664723098278046, + -0.1858849972486496, + -0.06051839143037796, + -0.19759516417980194, + -0.12695756554603577, + -0.12578172981739044, + -0.08346379548311234, + -0.43733522295951843 + ] + }, + { + "id": "/en/capturing_the_friedmans", + "directed_by": [ + "Andrew Jarecki" + ], + "initial_release_date": "2003-01-17", + "name": "Capturing the Friedmans", + "genre": [ + "Documentary film", + "Mystery", + "Biographical film" + ], + "film_vector": [ + 0.004712279886007309, + -0.11858777701854706, + 0.004940277896821499, + -0.08504702150821686, + 0.001116802915930748, + -0.3626813292503357, + -0.12055753171443939, + -0.07215794920921326, + 0.16848334670066833, + -0.14326728880405426 + ] + }, + { + "id": "/en/care_bears_journey_to_joke_a_lot", + "directed_by": [ + "Mike Fallows" + ], + "initial_release_date": "2004-10-05", + "name": "Care Bears: Journey to Joke-a-lot", + "genre": [ + "Musical", + "Computer Animation", + "Animation", + "Children's Fantasy", + "Children's/Family", + "Musical comedy", + "Comedy", + "Family" + ], + "film_vector": [ + 0.2494027018547058, + 0.16516828536987305, + -0.2278074324131012, + 0.3605857491493225, + -0.2081218808889389, + 0.09467808902263641, + 0.0911184698343277, + 0.09871038794517517, + 0.07976292073726654, + -0.08970028907060623 + ] + }, + { + "id": "/en/cargo_2006", + "directed_by": [ + "Clive Gordon" + ], + "initial_release_date": "2006-01-24", + "name": "Cargo", + "genre": [ + "Thriller", + "Psychological thriller", + "Indie film", + "Adventure Film", + "Drama" + ], + "film_vector": [ + -0.619398832321167, + -0.22115716338157654, + -0.3274936079978943, + 0.07621372491121292, + -0.0216545220464468, + -0.2260507196187973, + -0.03266272321343422, + -0.0744786411523819, + 0.037436578422784805, + 0.010756654664874077 + ] + }, + { + "id": "/en/cars", + "directed_by": [ + "John Lasseter", + "Joe Ranft" + ], + "initial_release_date": "2006-03-14", + "name": "Cars", + "genre": [ + "Animation", + "Family", + "Adventure Film", + "Sports", + "Comedy" + ], + "film_vector": [ + -0.33996617794036865, + 0.10096832364797592, + -0.17932257056236267, + 0.34555456042289734, + -0.45365309715270996, + 0.030475780367851257, + -0.06710363924503326, + -0.24490848183631897, + 0.1621592491865158, + -0.025119051337242126 + ] + }, + { + "id": "/en/casanova", + "directed_by": [ + "Lasse Hallstr\u00f6m" + ], + "initial_release_date": "2005-09-03", + "name": "Casanova", + "genre": [ + "Romance Film", + "Romantic comedy", + "Costume drama", + "Adventure Film", + "Historical period drama", + "Swashbuckler film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.458809494972229, + 0.07827489078044891, + -0.439555823802948, + 0.0985753983259201, + 0.030070031061768532, + -0.14696459472179413, + -0.16000139713287354, + 0.12575949728488922, + -0.07490091025829315, + -0.21985292434692383 + ] + }, + { + "id": "/en/case_of_evil", + "directed_by": [ + "Graham Theakston" + ], + "initial_release_date": "2002-10-25", + "name": "Sherlock: Case of Evil", + "genre": [ + "Mystery", + "Action Film", + "Adventure Film", + "Thriller", + "Crime Fiction", + "Drama" + ], + "film_vector": [ + -0.5216550827026367, + -0.15156064927577972, + -0.14415933191776276, + 0.07623075693845749, + -0.15558157861232758, + -0.06024006009101868, + 0.027393268421292305, + -0.026179008185863495, + -0.11957433819770813, + -0.2842264771461487 + ] + }, + { + "id": "/en/cast_away", + "initial_release_date": "2000-12-07", + "name": "Cast Away", + "directed_by": [ + "Robert Zemeckis" + ], + "genre": [ + "Airplanes and airports", + "Adventure Film", + "Action/Adventure", + "Drama" + ], + "film_vector": [ + -0.3484877943992615, + -0.008954368531703949, + -0.15775680541992188, + 0.24516689777374268, + -0.07027603685855865, + -0.08501581102609634, + -0.13839751482009888, + -0.09978452324867249, + -0.0058303046971559525, + -0.19718362390995026 + ] + }, + { + "id": "/en/castlevania_2007", + "name": "Castlevania", + "directed_by": [ + "Paul W. S. Anderson", + "Sylvain White" + ], + "genre": [ + "Action Film", + "Horror" + ], + "film_vector": [ + -0.18023335933685303, + -0.30751389265060425, + 0.07506567984819412, + 0.2376789152622223, + 0.23929914832115173, + -0.12240590155124664, + 0.037660520523786545, + 0.014436266385018826, + 0.014819992706179619, + -0.1610797494649887 + ] + }, + { + "id": "/en/catch_me_if_you_can", + "initial_release_date": "2002-12-16", + "name": "Catch Me If You Can", + "directed_by": [ + "Steven Spielberg" + ], + "genre": [ + "Crime Fiction", + "Comedy", + "Biographical film", + "Drama" + ], + "film_vector": [ + -0.45574408769607544, + -0.12628917396068573, + -0.289046049118042, + -0.03172110766172409, + -0.18807153403759003, + -0.20608745515346527, + -0.023420237004756927, + -0.19127488136291504, + 0.07179763913154602, + -0.25408509373664856 + ] + }, + { + "id": "/en/catch_that_kid", + "initial_release_date": "2004-02-06", + "name": "Catch That Kid", + "directed_by": [ + "Bart Freundlich" + ], + "genre": [ + "Teen film", + "Adventure Film", + "Crime Fiction", + "Family", + "Caper story", + "Children's/Family", + "Crime Comedy", + "Family-Oriented Adventure", + "Comedy" + ], + "film_vector": [ + -0.3465050458908081, + -0.17871923744678497, + -0.40329670906066895, + 0.2588273882865906, + -0.0940190851688385, + -0.07781363278627396, + -0.087871253490448, + -0.16379311680793762, + 0.06838854402303696, + -0.1298956274986267 + ] + }, + { + "id": "/en/caterina_in_the_big_city", + "initial_release_date": "2003-10-24", + "name": "Caterina in the Big City", + "directed_by": [ + "Paolo Virz\u00ec" + ], + "genre": [ + "Comedy", + "Drama" + ], + "film_vector": [ + -0.02233671396970749, + 0.1146913543343544, + -0.2835932970046997, + -0.06668701767921448, + 0.04618372023105621, + 0.04026419296860695, + 0.0594552606344223, + -0.10631361603736877, + 0.06434856355190277, + -0.20039916038513184 + ] + }, + { + "id": "/en/cats_dogs", + "initial_release_date": "2001-07-04", + "name": "Cats & Dogs", + "directed_by": [ + "Lawrence Guterman" + ], + "genre": [ + "Adventure Film", + "Family", + "Action Film", + "Children's/Family", + "Fantasy Adventure", + "Fantasy Comedy", + "Comedy" + ], + "film_vector": [ + -0.3107292056083679, + 0.05088478699326515, + -0.33841022849082947, + 0.45389097929000854, + -0.24128644168376923, + -0.03929176554083824, + -0.08701958507299423, + -0.01604107953608036, + 0.06970678269863129, + -0.19458866119384766 + ] + }, + { + "id": "/en/catwoman_2004", + "initial_release_date": "2004-07-19", + "name": "Catwoman", + "directed_by": [ + "Pitof" + ], + "genre": [ + "Action Film", + "Crime Fiction", + "Fantasy", + "Action/Adventure", + "Thriller", + "Superhero movie" + ], + "film_vector": [ + -0.5608767867088318, + -0.1527424156665802, + -0.28617745637893677, + 0.18385452032089233, + -0.12713278830051422, + -0.0049951281398534775, + -0.13815349340438843, + -0.09549988806247711, + 0.004371814429759979, + -0.12770730257034302 + ] + }, + { + "id": "/en/caved_in_prehistoric_terror", + "initial_release_date": "2006-01-07", + "name": "Caved In: Prehistoric Terror", + "directed_by": [ + "Richard Pepin" + ], + "genre": [ + "Science Fiction", + "Horror", + "Natural horror film", + "Monster", + "Fantasy", + "Television film", + "Creature Film", + "Sci-Fi Horror" + ], + "film_vector": [ + -0.34272903203964233, + -0.3395804166793823, + 0.04749962314963341, + 0.2442416399717331, + -0.10333562642335892, + -0.1475619673728943, + 0.11770294606685638, + 0.23216938972473145, + 0.13782863318920135, + -0.053252119570970535 + ] + }, + { + "id": "/en/cellular", + "initial_release_date": "2004-09-10", + "name": "Cellular", + "directed_by": [ + "David R. Ellis" + ], + "genre": [ + "Thriller", + "Action Film", + "Crime Thriller", + "Action/Adventure" + ], + "film_vector": [ + -0.6172856092453003, + -0.2845405340194702, + -0.21245405077934265, + 0.13296641409397125, + 0.09579251706600189, + -0.12236402928829193, + -0.02656783163547516, + -0.12795335054397583, + -0.03028573840856552, + 0.01678660698235035 + ] + }, + { + "id": "/en/center_stage", + "initial_release_date": "2000-05-12", + "name": "Center Stage", + "directed_by": [ + "Nicholas Hytner" + ], + "genre": [ + "Teen film", + "Dance film", + "Musical", + "Musical Drama", + "Ensemble Film", + "Drama" + ], + "film_vector": [ + -0.24595296382904053, + 0.08492814749479294, + -0.43643760681152344, + 0.019504718482494354, + -0.08847297728061676, + -0.14871467649936676, + -0.198147714138031, + 0.1624215692281723, + 0.15118351578712463, + 0.04184652119874954 + ] + }, + { + "id": "/en/chai_lai", + "initial_release_date": "2006-01-26", + "name": "Chai Lai", + "directed_by": [ + "Poj Arnon" + ], + "genre": [ + "Action Film", + "Martial Arts Film", + "Comedy" + ], + "film_vector": [ + -0.2500153183937073, + 0.17676329612731934, + -0.15093746781349182, + 0.14449827373027802, + 0.18166688084602356, + -0.24363312125205994, + 0.058773282915353775, + -0.17743533849716187, + 0.03402773290872574, + -0.14884260296821594 + ] + }, + { + "id": "/en/chain_2004", + "name": "Chain", + "directed_by": [ + "Jem Cohen" + ], + "genre": [ + "Documentary film" + ], + "film_vector": [ + -0.018211528658866882, + -0.06839677691459656, + 0.03351768106222153, + -0.014209001325070858, + 0.028740504756569862, + -0.4185146391391754, + -0.10836632549762726, + -0.07167014479637146, + 0.18165645003318787, + -0.023306291550397873 + ] + }, + { + "id": "/en/chakram_2005", + "initial_release_date": "2005-03-25", + "name": "Chakram", + "directed_by": [ + "Krishna Vamsi" + ], + "genre": [ + "Romance Film", + "Drama", + "Tollywood", + "World cinema" + ], + "film_vector": [ + -0.6006883382797241, + 0.3978409171104431, + -0.08425286412239075, + -0.016809985041618347, + 0.06701143085956573, + -0.09942404180765152, + 0.1340395212173462, + -0.14478106796741486, + 0.05334395170211792, + -0.05999847501516342 + ] + }, + { + "id": "/en/challenger_2007", + "name": "Challenger", + "directed_by": [ + "Philip Kaufman" + ], + "genre": [ + "Drama" + ], + "film_vector": [ + 0.08594280481338501, + 0.020342405885457993, + 0.0295710489153862, + -0.20266756415367126, + 0.03487488254904747, + 0.18459416925907135, + -0.17626240849494934, + -0.04847824573516846, + -0.14638370275497437, + 0.228578582406044 + ] + }, + { + "id": "/en/chalo_ishq_ladaaye", + "initial_release_date": "2002-12-27", + "name": "Chalo Ishq Ladaaye", + "directed_by": [ + "Aziz Sejawal" + ], + "genre": [ + "Romance Film", + "Comedy", + "Bollywood", + "World cinema" + ], + "film_vector": [ + -0.4506496787071228, + 0.4438707232475281, + -0.18172815442085266, + 0.06884723901748657, + 0.17815491557121277, + -0.12531080842018127, + 0.16560058295726776, + -0.10550080984830856, + 0.041585564613342285, + -0.05980681627988815 + ] + }, + { + "id": "/en/chalte_chalte", + "initial_release_date": "2003-06-12", + "name": "Chalte Chalte", + "directed_by": [ + "Aziz Mirza" + ], + "genre": [ + "Romance Film", + "Musical", + "Bollywood", + "Drama", + "Musical Drama" + ], + "film_vector": [ + -0.3153998851776123, + 0.31284281611442566, + -0.289736270904541, + 0.03862421587109566, + 0.2127799242734909, + -0.09268482029438019, + 0.02983066812157631, + -0.007427296135574579, + -0.037857767194509506, + -0.034376174211502075 + ] + }, + { + "id": "/en/chameli", + "initial_release_date": "2003-12-31", + "name": "Chameli", + "directed_by": [ + "Sudhir Mishra", + "Anant Balani" + ], + "genre": [ + "Romance Film", + "Bollywood", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.5800031423568726, + 0.3863193690776825, + -0.14759951829910278, + 0.028904207050800323, + 0.11793249845504761, + -0.06952165067195892, + 0.08892397582530975, + -0.09218607097864151, + 0.10473934561014175, + -0.07923664152622223 + ] + }, + { + "id": "/en/chandni_bar", + "initial_release_date": "2001-09-28", + "name": "Chandni Bar", + "directed_by": [ + "Madhur Bhandarkar" + ], + "genre": [ + "Crime Fiction", + "Bollywood", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.5613616704940796, + 0.2206396460533142, + -0.029147403314709663, + -0.17643582820892334, + -0.06996550410985947, + -0.021699512377381325, + 0.21250832080841064, + -0.16939885914325714, + 0.020227525383234024, + -0.25205886363983154 + ] + }, + { + "id": "/en/chandramukhi", + "initial_release_date": "2005-04-13", + "name": "Chandramukhi", + "directed_by": [ + "P. Vasu" + ], + "genre": [ + "Horror", + "World cinema", + "Musical", + "Horror comedy", + "Musical comedy", + "Comedy", + "Fantasy", + "Romance Film" + ], + "film_vector": [ + -0.5327794551849365, + 0.2245863974094391, + -0.14641061425209045, + 0.12932775914669037, + 0.08510411530733109, + -0.09274260699748993, + 0.21601001918315887, + 0.1123243048787117, + 0.06842407584190369, + -0.06521494686603546 + ] + }, + { + "id": "/en/changing_lanes", + "initial_release_date": "2002-04-07", + "name": "Changing Lanes", + "directed_by": [ + "Roger Michell" + ], + "genre": [ + "Thriller", + "Psychological thriller", + "Melodrama", + "Drama" + ], + "film_vector": [ + -0.4665045738220215, + -0.205020010471344, + -0.35077109932899475, + -0.16961440443992615, + -0.05269475653767586, + -0.013632843270897865, + -0.04188540577888489, + -0.0001162276603281498, + 0.006967461667954922, + -0.015287092886865139 + ] + }, + { + "id": "/en/chaos_2007", + "initial_release_date": "2005-12-15", + "name": "Chaos", + "directed_by": [ + "Tony Giglio" + ], + "genre": [ + "Thriller", + "Action Film", + "Crime Fiction", + "Heist film", + "Action/Adventure", + "Drama" + ], + "film_vector": [ + -0.5954116582870483, + -0.2315824180841446, + -0.22658471763134003, + -0.006007172167301178, + -0.058499135076999664, + -0.11355515569448471, + -0.024607403203845024, + -0.06587113440036774, + -0.021998370066285133, + -0.003768596798181534 + ] + }, + { + "id": "/en/chaos_2005", + "initial_release_date": "2005-08-10", + "name": "Chaos", + "directed_by": [ + "David DeFalco" + ], + "genre": [ + "Horror", + "Teen film", + "B movie", + "Slasher" + ], + "film_vector": [ + -0.3632338047027588, + -0.3329789638519287, + -0.1346154510974884, + 0.1815621703863144, + 0.13714301586151123, + -0.10307475179433823, + 0.14906176924705505, + 0.05550134927034378, + 0.16853848099708557, + 0.024396374821662903 + ] + }, + { + "id": "/en/chaos_and_creation_at_abbey_road", + "initial_release_date": "2006-01-27", + "name": "Chaos and Creation at Abbey Road", + "directed_by": [ + "Simon Hilton" + ], + "genre": [ + "Musical" + ], + "film_vector": [ + 0.11677660048007965, + 0.017697995528578758, + -0.047003891319036484, + -0.14072705805301666, + 0.012435092590749264, + 0.027394209057092667, + -0.06421822309494019, + 0.35210922360420227, + 0.12074632942676544, + 0.01805894821882248 + ] + }, + { + "id": "/en/chaos_theory_2007", + "name": "Chaos Theory", + "directed_by": [ + "Marcos Siega" + ], + "genre": [ + "Romance Film", + "Romantic comedy", + "Comedy-drama", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.23420530557632446, + 0.004736408591270447, + -0.3227091133594513, + -0.07190515100955963, + 0.1424940526485443, + 0.012415992096066475, + -0.001468215836212039, + 0.15165546536445618, + 0.01760304532945156, + -0.057814694941043854 + ] + }, + { + "id": "/en/chapter_27", + "initial_release_date": "2007-01-25", + "name": "Chapter 27", + "directed_by": [ + "Jarrett Schaefer" + ], + "genre": [ + "Indie film", + "Crime Fiction", + "Biographical film", + "Drama" + ], + "film_vector": [ + -0.43852031230926514, + -0.17186611890792847, + -0.25278913974761963, + -0.1629638969898224, + -0.02173611894249916, + -0.29240500926971436, + -0.07592707872390747, + -0.18865522742271423, + 0.1410745084285736, + -0.2876625061035156 + ] + }, + { + "id": "/en/charlie_and_the_chocolate_factory_2005", + "initial_release_date": "2005-07-10", + "name": "Charlie and the Chocolate Factory", + "directed_by": [ + "Tim Burton" + ], + "genre": [ + "Fantasy", + "Remake", + "Adventure Film", + "Family", + "Children's Fantasy", + "Children's/Family", + "Comedy" + ], + "film_vector": [ + -0.08188382536172867, + 0.004298683255910873, + -0.3395458161830902, + 0.3750431537628174, + 0.03662831336259842, + -0.0629054456949234, + -0.10669994354248047, + 0.10928329080343246, + 0.00700834346935153, + -0.30736255645751953 + ] + }, + { + "id": "/en/charlies_angels", + "initial_release_date": "2000-10-22", + "name": "Charlie's Angels", + "directed_by": [ + "Joseph McGinty Nichol" + ], + "genre": [ + "Action Film", + "Crime Fiction", + "Comedy", + "Adventure Film", + "Thriller" + ], + "film_vector": [ + -0.3955497443675995, + -0.21678847074508667, + -0.3759932518005371, + 0.12000128626823425, + -0.015102081000804901, + -0.10099273920059204, + -0.12079952657222748, + -0.130329892039299, + 0.03061983734369278, + -0.1733241081237793 + ] + }, + { + "id": "/en/charlies_angels_full_throttle", + "initial_release_date": "2003-06-18", + "name": "Charlie's Angels: Full Throttle", + "directed_by": [ + "Joseph McGinty Nichol" + ], + "genre": [ + "Martial Arts Film", + "Action Film", + "Adventure Film", + "Crime Fiction", + "Action/Adventure", + "Action Comedy", + "Comedy" + ], + "film_vector": [ + -0.2355230301618576, + -0.12190619856119156, + -0.2923651933670044, + 0.19869521260261536, + -0.04638077691197395, + -0.14350402355194092, + -0.16282877326011658, + -0.08691293746232986, + -0.05641699209809303, + -0.10011406242847443 + ] + }, + { + "id": "/en/charlotte_gray", + "initial_release_date": "2001-12-17", + "name": "Charlotte Gray", + "directed_by": [ + "Gillian Armstrong" + ], + "genre": [ + "Romance Film", + "War film", + "Political drama", + "Historical period drama", + "Film adaptation", + "Drama" + ], + "film_vector": [ + -0.3500385880470276, + 0.03577226400375366, + -0.22498363256454468, + -0.12060514092445374, + 0.057824213057756424, + -0.1498512327671051, + -0.1907830834388733, + 0.14415019750595093, + 0.02015715278685093, + -0.3418322205543518 + ] + }, + { + "id": "/en/charlottes_web", + "initial_release_date": "2006-12-07", + "name": "Charlotte's Web", + "directed_by": [ + "Gary Winick" + ], + "genre": [ + "Animation", + "Family", + "Comedy" + ], + "film_vector": [ + 0.06630685925483704, + 0.05956251919269562, + -0.1817411482334137, + 0.2622900903224945, + -0.20400021970272064, + 0.19247567653656006, + 0.08710263669490814, + -0.1077519878745079, + 0.21929308772087097, + -0.14020439982414246 + ] + }, + { + "id": "/en/chasing_liberty", + "initial_release_date": "2004-01-07", + "name": "Chasing Liberty", + "directed_by": [ + "Andy Cadiff" + ], + "genre": [ + "Romantic comedy", + "Teen film", + "Romance Film", + "Road movie", + "Comedy" + ], + "film_vector": [ + -0.34155911207199097, + -0.02691844291985035, + -0.4768833816051483, + 0.18623261153697968, + 0.14633414149284363, + -0.2719021439552307, + -0.1439180076122284, + -0.15487778186798096, + 0.04537162184715271, + -0.04437728226184845 + ] + }, + { + "id": "/en/chasing_papi", + "initial_release_date": "2003-04-16", + "name": "Chasing Papi", + "directed_by": [ + "Linda Mendoza" + ], + "genre": [ + "Romance Film", + "Romantic comedy", + "Farce", + "Chase Movie", + "Comedy" + ], + "film_vector": [ + -0.31504857540130615, + 0.08032940328121185, + -0.4439171552658081, + 0.12980327010154724, + 0.21744504570960999, + -0.13671930134296417, + 0.001986129442229867, + 0.03563333675265312, + -0.09289602935314178, + -0.05729544907808304 + ] + }, + { + "id": "/en/chasing_sleep", + "initial_release_date": "2001-09-16", + "name": "Chasing Sleep", + "directed_by": [ + "Michael Walker" + ], + "genre": [ + "Mystery", + "Psychological thriller", + "Surrealism", + "Thriller", + "Indie film", + "Suspense", + "Crime Thriller" + ], + "film_vector": [ + -0.5068423748016357, + -0.34025484323501587, + -0.20860561728477478, + 0.026524608954787254, + 0.05400927737355232, + -0.1541319340467453, + 0.08506524562835693, + 0.06615134328603745, + 0.18254481256008148, + -0.047707825899124146 + ] + }, + { + "id": "/en/chasing_the_horizon", + "initial_release_date": "2006-04-26", + "name": "Chasing the Horizon", + "directed_by": [ + "Markus Canter", + "Mason Canter" + ], + "genre": [ + "Documentary film", + "Auto racing" + ], + "film_vector": [ + -0.020517753437161446, + -0.04115378111600876, + 0.1380120813846588, + -0.06680260598659515, + -0.0023790672421455383, + -0.3198240399360657, + -0.2573666572570801, + -0.17490741610527039, + 0.1279720813035965, + 0.05398387089371681 + ] + }, + { + "id": "/en/chathikkatha_chanthu", + "initial_release_date": "2004-04-14", + "name": "Chathikkatha Chanthu", + "directed_by": [ + "Meccartin" + ], + "genre": [ + "Comedy", + "Malayalam Cinema", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.5200599431991577, + 0.40677279233932495, + -0.07388519495725632, + 0.06336874514818192, + -0.03969309478998184, + -0.11684050410985947, + 0.22932711243629456, + -0.0074557652696967125, + -0.004476431757211685, + -0.08512634038925171 + ] + }, + { + "id": "/en/chatrapati", + "initial_release_date": "2005-09-25", + "name": "Chhatrapati", + "directed_by": [ + "S. S. Rajamouli" + ], + "genre": [ + "Action Film", + "Tollywood", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.5730847120285034, + 0.36545711755752563, + 0.04585380107164383, + -0.004363566637039185, + 0.015798326581716537, + -0.14186066389083862, + 0.1522546112537384, + -0.1366133838891983, + -0.10329736024141312, + -0.06894814968109131 + ] + }, + { + "id": "/en/cheaper_by_the_dozen_2003", + "initial_release_date": "2003-12-25", + "name": "Cheaper by the Dozen", + "directed_by": [ + "Shawn Levy" + ], + "genre": [ + "Family", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.10087205469608307, + -0.07016646862030029, + -0.5360488891601562, + 0.17801478505134583, + -0.07405432313680649, + -0.04893939942121506, + 0.02265963703393936, + -0.21210455894470215, + 0.03393511474132538, + -0.10868431627750397 + ] + }, + { + "id": "/en/cheaper_by_the_dozen_2", + "initial_release_date": "2005-12-21", + "name": "Cheaper by the Dozen 2", + "directed_by": [ + "Adam Shankman" + ], + "genre": [ + "Family", + "Adventure Film", + "Domestic Comedy", + "Comedy" + ], + "film_vector": [ + -0.16103827953338623, + -0.08053421974182129, + -0.5331969857215881, + 0.33160150051116943, + -0.03044242598116398, + -0.16853661835193634, + 0.0036609750241041183, + -0.14580197632312775, + -0.04144981876015663, + -0.11562845855951309 + ] + }, + { + "id": "/en/checking_out_2005", + "initial_release_date": "2005-04-10", + "name": "Checking Out", + "directed_by": [ + "Jeff Hare" + ], + "genre": [ + "Black comedy", + "Comedy" + ], + "film_vector": [ + 0.013628361746668816, + -0.0009132055565714836, + -0.3380526006221771, + -0.09966558963060379, + -0.2488180696964264, + -0.13937154412269592, + 0.32844078540802, + -0.13174760341644287, + 0.12132725119590759, + -0.18397390842437744 + ] + }, + { + "id": "/en/chellamae", + "initial_release_date": "2004-09-10", + "name": "Chellamae", + "directed_by": [ + "Gandhi Krishna" + ], + "genre": [ + "Romance Film", + "Tamil cinema", + "World cinema" + ], + "film_vector": [ + -0.5480238199234009, + 0.4205583930015564, + -0.07122315466403961, + 0.029212232679128647, + 0.20961794257164001, + -0.09378495812416077, + 0.06990379095077515, + -0.07198350131511688, + 0.035230543464422226, + -0.11021269857883453 + ] + }, + { + "id": "/en/chemman_chaalai", + "name": "Chemman Chaalai", + "directed_by": [ + "Deepak Kumaran Menon" + ], + "genre": [ + "Tamil cinema", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.48751237988471985, + 0.42473873496055603, + 0.07092275470495224, + -0.017002826556563377, + 0.04772329330444336, + -0.13239571452140808, + 0.11413995921611786, + -0.08040140569210052, + 0.04455176740884781, + -0.08907250314950943 + ] + }, + { + "id": "/en/chennaiyil_oru_mazhai_kaalam", + "name": "Chennaiyil Oru Mazhai Kaalam", + "directed_by": [ + "Prabhu Deva" + ], + "genre": [], + "film_vector": [ + -0.16850847005844116, + 0.346246600151062, + 0.10127460211515427, + -0.08076217770576477, + 0.16798242926597595, + 0.08337466418743134, + 0.21032561361789703, + -0.005577034316956997, + -0.06385239213705063, + 0.07012630254030228 + ] + }, + { + "id": "/en/cher_the_farewell_tour_live_in_miami", + "initial_release_date": "2003-08-26", + "name": "The Farewell Tour", + "directed_by": [ + "Dorina Sanchez", + "David Mallet" + ], + "genre": [ + "Music video" + ], + "film_vector": [ + 0.10742887854576111, + -0.0016661491245031357, + 0.0011131446808576584, + -0.024877285584807396, + 0.16630765795707703, + -0.2560853064060211, + -0.07714375853538513, + 0.03964677453041077, + 0.15004004538059235, + 0.25449416041374207 + ] + }, + { + "id": "/en/cherry_falls", + "initial_release_date": "2000-07-29", + "name": "Cherry Falls", + "directed_by": [ + "Geoffrey Wright" + ], + "genre": [ + "Satire", + "Slasher", + "Indie film", + "Horror", + "Horror comedy", + "Comedy" + ], + "film_vector": [ + -0.2318546622991562, + -0.2451387643814087, + -0.3820217251777649, + 0.06898625940084457, + -0.06965013593435287, + -0.1666574776172638, + 0.16843050718307495, + 0.016720000654459, + 0.18127821385860443, + -0.1237996518611908 + ] + }, + { + "id": "/wikipedia/en_title/Chess_$00282006_film$0029", + "initial_release_date": "2006-07-07", + "name": "Chess", + "directed_by": [ + "RajBabu" + ], + "genre": [ + "Crime Fiction", + "Thriller", + "Action Film", + "Comedy", + "Malayalam Cinema", + "World cinema" + ], + "film_vector": [ + -0.6660122871398926, + 0.18646663427352905, + -0.030874349176883698, + -0.008240960538387299, + -0.12609213590621948, + -0.07320085912942886, + 0.13431598246097565, + -0.1280824840068817, + -0.0006139795295894146, + -0.10408797860145569 + ] + }, + { + "id": "/en/chica_de_rio", + "initial_release_date": "2003-04-11", + "name": "Girl from Rio", + "directed_by": [ + "Christopher Monger" + ], + "genre": [ + "Romantic comedy", + "Romance Film", + "Comedy" + ], + "film_vector": [ + -0.20913949608802795, + 0.16893541812896729, + -0.34934741258621216, + 0.1490963101387024, + 0.37731581926345825, + -0.07984482496976852, + -0.03735421970486641, + -0.08319699019193649, + 0.1584273725748062, + -0.14473159611225128 + ] + }, + { + "id": "/en/chicago_2002", + "initial_release_date": "2002-12-10", + "name": "Chicago", + "directed_by": [ + "Rob Marshall" + ], + "genre": [ + "Musical", + "Crime Fiction", + "Comedy", + "Musical comedy" + ], + "film_vector": [ + -0.17713257670402527, + -0.04780150577425957, + -0.479339063167572, + -0.16711410880088806, + -0.1381981074810028, + -0.13132447004318237, + 0.04726112261414528, + -0.05990537628531456, + 0.024363812059164047, + -0.2752676010131836 + ] + }, + { + "id": "/en/chicken_little", + "initial_release_date": "2005-10-30", + "name": "Chicken Little", + "directed_by": [ + "Mark Dindal" + ], + "genre": [ + "Animation", + "Adventure Film", + "Comedy" + ], + "film_vector": [ + -0.07336778938770294, + 0.11129777133464813, + -0.16067133843898773, + 0.48384177684783936, + -0.18737009167671204, + -0.04001547768712044, + 1.982972025871277e-05, + -0.17612789571285248, + 0.11000914871692657, + -0.1608130931854248 + ] + }, + { + "id": "/en/chicken_run", + "initial_release_date": "2000-06-21", + "name": "Chicken Run", + "directed_by": [ + "Peter Lord", + "Nick Park" + ], + "genre": [ + "Family", + "Animation", + "Comedy" + ], + "film_vector": [ + 0.11658064275979996, + 0.08577200770378113, + -0.22538158297538757, + 0.33562204241752625, + -0.2178535759449005, + -0.031962040811777115, + 0.05709032341837883, + -0.2184215635061264, + 0.04707758128643036, + -0.11332082003355026 + ] + }, + { + "id": "/en/child_marriage_2005", + "name": "Child Marriage", + "directed_by": [ + "Neeraj Kumar" + ], + "genre": [ + "Documentary film" + ], + "film_vector": [ + 0.08639217913150787, + 0.03502490371465683, + -0.0631001889705658, + -0.0017805092502385378, + 0.17429766058921814, + -0.2042306363582611, + -0.11494085937738419, + -0.10512331128120422, + 0.24137040972709656, + -0.09960176050662994 + ] + }, + { + "id": "/en/children_of_men", + "initial_release_date": "2006-09-03", + "name": "Children of Men", + "directed_by": [ + "Alfonso Cuar\u00f3n" + ], + "genre": [ + "Thriller", + "Action Film", + "Science Fiction", + "Dystopia", + "Doomsday film", + "Future noir", + "Mystery", + "Adventure Film", + "Film adaptation", + "Action Thriller", + "Drama" + ], + "film_vector": [ + -0.592212438583374, + -0.2049904465675354, + -0.30199846625328064, + 0.06069602817296982, + -0.12371133267879486, + -0.19030684232711792, + -0.12595133483409882, + 0.030880354344844818, + 0.02939077839255333, + -0.04083719104528427 + ] + }, + { + "id": "/en/children_of_the_corn_revelation", + "initial_release_date": "2001-10-09", + "name": "Children of the Corn: Revelation", + "directed_by": [ + "Guy Magar" + ], + "genre": [ + "Horror", + "Supernatural", + "Cult film" + ], + "film_vector": [ + -0.06144705042243004, + -0.2836056351661682, + -0.027762139216065407, + 0.08033512532711029, + 0.14490102231502533, + -0.2442478984594345, + 0.07685321569442749, + 0.1515657603740692, + 0.16522002220153809, + -0.13948500156402588 + ] + }, + { + "id": "/en/children_of_the_living_dead", + "name": "Children of the Living Dead", + "directed_by": [ + "Tor Ramsey" + ], + "genre": [ + "Indie film", + "Teen film", + "Horror", + "Zombie Film", + "Horror comedy" + ], + "film_vector": [ + -0.3918602466583252, + -0.28906840085983276, + -0.2827172577381134, + 0.2431405484676361, + -0.07588062435388565, + -0.2582390606403351, + 0.14151659607887268, + 0.055439360439777374, + 0.3001677989959717, + -0.013663615100085735 + ] + }, + { + "id": "/en/chinthamani_kolacase", + "initial_release_date": "2006-03-31", + "name": "Chinthamani Kolacase", + "directed_by": [ + "Shaji Kailas" + ], + "genre": [ + "Horror", + "Mystery", + "Crime Fiction", + "Action Film", + "Thriller", + "Malayalam Cinema", + "World cinema" + ], + "film_vector": [ + -0.655497670173645, + 0.10997983068227768, + -0.025388892740011215, + 0.015516307204961777, + 0.031526919454336166, + -0.07595565170049667, + 0.18571513891220093, + -0.10095804929733276, + 0.01820497214794159, + -0.12004762142896652 + ] + }, + { + "id": "/en/chips_2008", + "name": "CHiPs", + "directed_by": [], + "genre": [ + "Musical", + "Children's/Family" + ], + "film_vector": [ + 0.10411538183689117, + 0.034246258437633514, + -0.30436432361602783, + 0.12998557090759277, + -0.07507403194904327, + 0.022243909537792206, + 0.017418507486581802, + -0.028713969513773918, + 0.1637028455734253, + -0.018135037273168564 + ] + }, + { + "id": "/en/chithiram_pesuthadi", + "initial_release_date": "2006-02-10", + "name": "Chithiram Pesuthadi", + "directed_by": [ + "Mysskin" + ], + "genre": [ + "Romance Film", + "Tamil cinema", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.45618903636932373, + 0.37290382385253906, + -0.043174900114536285, + 0.018141375854611397, + 0.2417871356010437, + -0.07203823328018188, + 0.06333006173372269, + -0.028620393946766853, + -0.023954257369041443, + -0.13553735613822937 + ] + }, + { + "id": "/en/chocolat_2000", + "initial_release_date": "2000-12-15", + "name": "Chocolat", + "directed_by": [ + "Lasse Hallstr\u00f6m" + ], + "genre": [ + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.1515813022851944, + 0.07300242781639099, + -0.3439367413520813, + 0.06755199283361435, + 0.42824381589889526, + -0.005601992830634117, + 0.0270390622317791, + -0.06774188578128815, + 0.14122319221496582, + -0.2504173219203949 + ] + }, + { + "id": "/en/choose_your_own_adventure_the_abominable_snowman", + "initial_release_date": "2006-07-25", + "name": "Choose Your Own Adventure The Abominable Snowman", + "directed_by": [ + "Bob Doucette" + ], + "genre": [ + "Adventure Film", + "Family", + "Children's/Family", + "Family-Oriented Adventure", + "Animation" + ], + "film_vector": [ + -0.02633463218808174, + -0.09056108444929123, + -0.07978872954845428, + 0.45905759930610657, + 0.03426799178123474, + -0.06953288614749908, + -0.08134812116622925, + 0.051338080316782, + -0.018242714926600456, + -0.12219108641147614 + ] + }, + { + "id": "/en/chopin_desire_for_love", + "initial_release_date": "2002-03-01", + "name": "Chopin: Desire for Love", + "directed_by": [ + "Jerzy Antczak" + ], + "genre": [ + "Biographical film", + "Romance Film", + "Music", + "Drama" + ], + "film_vector": [ + -0.2594292163848877, + 0.1109355166554451, + -0.10428214818239212, + -0.03506999462842941, + 0.21339797973632812, + -0.19342797994613647, + -0.14114925265312195, + 0.08436131477355957, + 0.10951410233974457, + -0.301655650138855 + ] + }, + { + "id": "/en/chopper", + "initial_release_date": "2000-08-03", + "name": "Chopper", + "directed_by": [ + "Andrew Dominik" + ], + "genre": [ + "Biographical film", + "Crime Fiction", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.27417775988578796, + -0.17785915732383728, + -0.08242378383874893, + 0.002283714711666107, + -0.05672126263380051, + -0.22575044631958008, + 0.09626969695091248, + -0.19381578266620636, + -0.13262052834033966, + -0.13413117825984955 + ] + }, + { + "id": "/en/chori_chori_2003", + "initial_release_date": "2003-08-01", + "name": "Chori Chori", + "directed_by": [ + "Milan Luthria" + ], + "genre": [ + "Romance Film", + "Musical", + "Romantic comedy", + "Musical comedy", + "Comedy", + "Bollywood", + "World cinema", + "Drama", + "Musical Drama" + ], + "film_vector": [ + -0.501869261264801, + 0.35722628235816956, + -0.39224711060523987, + 0.052290625870227814, + 0.09473779052495956, + -0.08812540769577026, + 0.06740431487560272, + 0.15657950937747955, + -0.046461015939712524, + 0.0019072908908128738 + ] + }, + { + "id": "/en/chori_chori_chupke_chupke", + "initial_release_date": "2001-03-09", + "name": "Chori Chori Chupke Chupke", + "directed_by": [ + "Abbas Burmawalla", + "Mustan Burmawalla" + ], + "genre": [ + "Romance Film", + "Musical", + "Bollywood", + "World cinema", + "Drama", + "Musical Drama" + ], + "film_vector": [ + -0.42479610443115234, + 0.3803580403327942, + -0.22855781018733978, + 0.061854809522628784, + 0.10520494729280472, + -0.08054395020008087, + 0.1448766440153122, + 0.02913014590740204, + -0.0027721039950847626, + -0.013200635090470314 + ] + }, + { + "id": "/en/christinas_house", + "initial_release_date": "2000-02-24", + "name": "Christina's House", + "directed_by": [ + "Gavin Wilding" + ], + "genre": [ + "Thriller", + "Mystery", + "Horror", + "Teen film", + "Slasher", + "Psychological thriller", + "Drama" + ], + "film_vector": [ + -0.44626152515411377, + -0.29773566126823425, + -0.3538302183151245, + 0.052437957376241684, + 0.12208378314971924, + 0.0028862678445875645, + -0.0381673201918602, + 0.04138367995619774, + 0.2424757331609726, + -0.01652568206191063 + ] + }, + { + "id": "/en/christmas_with_the_kranks", + "initial_release_date": "2004-11-24", + "name": "Christmas with the Kranks", + "directed_by": [ + "Joe Roth" + ], + "genre": [ + "Christmas movie", + "Family", + "Film adaptation", + "Slapstick", + "Holiday Film", + "Comedy" + ], + "film_vector": [ + 0.09340706467628479, + 0.010811524465680122, + -0.33119940757751465, + 0.23550927639007568, + 0.038659725338220596, + -0.17390206456184387, + 0.11824774742126465, + 0.09657823294401169, + -0.1254127323627472, + -0.1971280723810196 + ] + }, + { + "id": "/en/chromophobia", + "initial_release_date": "2005-05-21", + "name": "Chromophobia", + "directed_by": [ + "Martha Fiennes" + ], + "genre": [ + "Family Drama", + "Drama" + ], + "film_vector": [ + 0.034818731248378754, + -0.125738263130188, + -0.06865682452917099, + -0.139184832572937, + 0.00883896928280592, + 0.2403922826051712, + 0.11448153853416443, + 0.1589566320180893, + 0.19596093893051147, + -0.0913158431649208 + ] + }, + { + "id": "/en/chubby_killer", + "name": "Chubby Killer", + "directed_by": [ + "Reuben Rox" + ], + "genre": [ + "Slasher", + "Indie film", + "Horror" + ], + "film_vector": [ + -0.18983986973762512, + -0.36287328600883484, + -0.0988931655883789, + 0.17018955945968628, + 0.21937355399131775, + -0.1981436312198639, + 0.29528185725212097, + -0.11463187634944916, + 0.1471254527568817, + -0.06858725845813751 + ] + }, + { + "id": "/en/chukkallo_chandrudu", + "initial_release_date": "2006-01-14", + "name": "Chukkallo Chandrudu", + "directed_by": [ + "Siva Kumar" + ], + "genre": [ + "Comedy", + "Tollywood", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.4763617515563965, + 0.423704594373703, + -0.07908374071121216, + -0.001983635127544403, + -0.054955773055553436, + -0.14106465876102448, + 0.2697370946407318, + -0.1174287497997284, + 0.03837139904499054, + -0.11674222350120544 + ] + }, + { + "id": "/en/chup_chup_ke", + "initial_release_date": "2006-06-09", + "name": "Chup Chup Ke", + "directed_by": [ + "Priyadarshan", + "Kookie Gulati" + ], + "genre": [ + "Romantic comedy", + "Comedy", + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.39055681228637695, + 0.23989522457122803, + -0.4964517652988434, + 0.07547596096992493, + 0.11256712675094604, + -0.05782720446586609, + 0.09080450236797333, + -0.0656573697924614, + 0.031361475586891174, + -0.06734754890203476 + ] + }, + { + "id": "/en/church_ball", + "initial_release_date": "2006-03-17", + "name": "Church Ball", + "directed_by": [ + "Kurt Hale" + ], + "genre": [ + "Family", + "Sports", + "Comedy" + ], + "film_vector": [ + 0.184749573469162, + 0.09935638308525085, + -0.3442021608352661, + -0.006447602063417435, + -0.29171717166900635, + 0.1020045131444931, + 0.011747903190553188, + -0.19864656031131744, + 0.04883063584566116, + -0.030868172645568848 + ] + }, + { + "id": "/en/churchill_the_hollywood_years", + "initial_release_date": "2004-12-03", + "name": "Churchill: The Hollywood Years", + "directed_by": [ + "Peter Richardson" + ], + "genre": [ + "Satire", + "Comedy" + ], + "film_vector": [ + 0.038128916174173355, + 0.19712671637535095, + -0.0981786847114563, + -0.10859709233045578, + -0.17444701492786407, + -0.27908265590667725, + 0.03463929891586304, + 9.842030704021454e-05, + -0.1407456398010254, + -0.37747371196746826 + ] + }, + { + "id": "/en/cinderella_iii", + "initial_release_date": "2007-02-06", + "name": "Cinderella III: A Twist in Time", + "directed_by": [ + "Frank Nissen" + ], + "genre": [ + "Family", + "Animated cartoon", + "Fantasy", + "Romance Film", + "Animation", + "Children's/Family" + ], + "film_vector": [ + -0.11198783665895462, + 0.04819686710834503, + -0.15185561776161194, + 0.4284968376159668, + 0.13128221035003662, + 0.1253693848848343, + -0.18341168761253357, + 0.050980210304260254, + 0.1255832314491272, + -0.23724979162216187 + ] + }, + { + "id": "/en/cinderella_man", + "initial_release_date": "2005-05-23", + "name": "Cinderella Man", + "directed_by": [ + "Ron Howard" + ], + "genre": [ + "Biographical film", + "Historical period drama", + "Romance Film", + "Sports", + "Drama" + ], + "film_vector": [ + -0.33265042304992676, + 0.1325804442167282, + -0.23866787552833557, + 0.017601456493139267, + -0.04371357709169388, + -0.10036163032054901, + -0.2660616338253021, + 0.07568225264549255, + -0.026404721662402153, + -0.262967050075531 + ] + }, + { + "id": "/en/cinemania", + "name": "Cinemania", + "directed_by": [ + "Angela Christlieb", + "Stephen Kijak" + ], + "genre": [ + "Documentary film", + "Culture & Society" + ], + "film_vector": [ + -0.1546725034713745, + 0.21292060613632202, + 0.101549431681633, + -0.1287423074245453, + -0.07787221670150757, + -0.33312302827835083, + -0.06676957756280899, + -0.019341953098773956, + 0.3639370799064636, + -0.10339266806840897 + ] + }, + { + "id": "/en/city_of_ghosts", + "initial_release_date": "2003-03-27", + "name": "City of Ghosts", + "directed_by": [ + "Matt Dillon" + ], + "genre": [ + "Thriller", + "Crime Fiction", + "Crime Thriller", + "Drama" + ], + "film_vector": [ + -0.5126579999923706, + -0.39089059829711914, + -0.19350463151931763, + -0.13305464386940002, + -0.0185253769159317, + -0.018917184323072433, + 0.1361829787492752, + 0.041149359196424484, + 0.11839484423398972, + -0.18231657147407532 + ] + }, + { + "id": "/en/city_of_god", + "initial_release_date": "2002-05-18", + "name": "City of God", + "directed_by": [ + "Fernando Meirelles" + ], + "genre": [ + "Crime Fiction", + "Drama" + ], + "film_vector": [ + -0.288189172744751, + -0.1837591826915741, + -0.06010029464960098, + -0.2477908432483673, + -0.042045578360557556, + 0.05888134986162186, + -0.004253409802913666, + -0.09816874563694, + 0.0347776859998703, + -0.3295798897743225 + ] + }, + { + "id": "/en/claustrophobia_2003", + "name": "Claustrophobia", + "directed_by": [ + "Mark Tapio Kines" + ], + "genre": [ + "Slasher", + "Horror" + ], + "film_vector": [ + -0.18699751794338226, + -0.45657849311828613, + -0.007685698568820953, + 0.08971357345581055, + 0.14052926003932953, + -0.06194012612104416, + 0.279897004365921, + 0.15240666270256042, + 0.13331656157970428, + -0.037249647080898285 + ] + }, + { + "id": "/en/clean", + "initial_release_date": "2004-03-27", + "name": "Clean", + "directed_by": [ + "Olivier Assayas" + ], + "genre": [ + "Music", + "Drama" + ], + "film_vector": [ + -0.024130357429385185, + 0.0825323611497879, + -0.17673856019973755, + -0.2710469365119934, + -0.06587661057710648, + 0.11403251439332962, + -0.027996351942420006, + 0.031964026391506195, + 0.27060192823410034, + 0.14498092234134674 + ] + }, + { + "id": "/en/clear_cut_the_story_of_philomath_oregon", + "initial_release_date": "2006-01-20", + "name": "Clear Cut: The Story of Philomath, Oregon", + "directed_by": [ + "Peter Richardson" + ], + "genre": [ + "Documentary film" + ], + "film_vector": [ + 0.07034731656312943, + -0.07432867586612701, + 0.05296293646097183, + -0.08452193439006805, + -0.020838908851146698, + -0.3652455508708954, + -0.22391292452812195, + -0.06213728338479996, + 0.1855919361114502, + -0.11589284241199493 + ] + }, + { + "id": "/en/clerks_ii", + "initial_release_date": "2006-05-26", + "name": "Clerks II", + "directed_by": [ + "Kevin Smith" + ], + "genre": [ + "Buddy film", + "Workplace Comedy", + "Comedy" + ], + "film_vector": [ + 0.08398992568254471, + -0.06993351876735687, + -0.40447521209716797, + 0.18085604906082153, + 0.06313180178403854, + -0.3061091899871826, + 0.1832803636789322, + -0.19336780905723572, + -0.14889651536941528, + -0.038626886904239655 + ] + }, + { + "id": "/en/click", + "initial_release_date": "2006-06-22", + "name": "Click", + "directed_by": [ + "Frank Coraci" + ], + "genre": [ + "Comedy", + "Fantasy", + "Drama" + ], + "film_vector": [ + -0.28668785095214844, + 0.056760869920253754, + -0.25967323780059814, + 0.1228782907128334, + -0.27043938636779785, + 0.11278526484966278, + 0.004113469738513231, + -0.05294163525104523, + 0.14673158526420593, + -0.14677853882312775 + ] + }, + { + "id": "/en/clockstoppers", + "initial_release_date": "2002-03-29", + "name": "Clockstoppers", + "directed_by": [ + "Jonathan Frakes" + ], + "genre": [ + "Science Fiction", + "Teen film", + "Family", + "Thriller", + "Adventure Film", + "Comedy" + ], + "film_vector": [ + -0.3293750584125519, + -0.19333595037460327, + -0.2778199315071106, + 0.289436936378479, + 0.04524591192603111, + -0.07714182138442993, + -0.045204292982816696, + -0.16613608598709106, + 0.10572625696659088, + -0.04497663304209709 + ] + }, + { + "id": "/en/closer_2004", + "initial_release_date": "2004-12-03", + "name": "Closer", + "directed_by": [ + "Mike Nichols" + ], + "genre": [ + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.2366153597831726, + 0.022782402113080025, + -0.35408708453178406, + 0.024597108364105225, + 0.4916800558567047, + -0.0170461293309927, + -0.10024053603410721, + -0.1277669370174408, + 0.0895363986492157, + -0.08188846707344055 + ] + }, + { + "id": "/en/closing_the_ring", + "initial_release_date": "2007-09-14", + "name": "Closing the Ring", + "directed_by": [ + "Richard Attenborough" + ], + "genre": [ + "War film", + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.34861066937446594, + 0.03847774118185043, + -0.12595823407173157, + 0.04309941455721855, + 0.13287168741226196, + -0.09399634599685669, + -0.14897200465202332, + -0.0600864440202713, + -0.021345850080251694, + -0.13535895943641663 + ] + }, + { + "id": "/en/club_dread", + "initial_release_date": "2004-02-27", + "name": "Club Dread", + "directed_by": [ + "Jay Chandrasekhar" + ], + "genre": [ + "Parody", + "Horror", + "Slasher", + "Black comedy", + "Indie film", + "Horror comedy", + "Comedy" + ], + "film_vector": [ + -0.23934581875801086, + -0.23097041249275208, + -0.3603111505508423, + 0.030373936519026756, + -0.15173916518688202, + -0.1957591474056244, + 0.34836626052856445, + 0.18200740218162537, + 0.09071099013090134, + -0.04621594399213791 + ] + }, + { + "id": "/en/coach_carter", + "initial_release_date": "2005-01-13", + "name": "Coach Carter", + "directed_by": [ + "Thomas Carter" + ], + "genre": [ + "Coming of age", + "Sports", + "Docudrama", + "Biographical film", + "Drama" + ], + "film_vector": [ + -0.09336835145950317, + 0.07983414828777313, + -0.18966922163963318, + -0.10936425626277924, + -0.0534215122461319, + -0.23889555037021637, + -0.22029352188110352, + -0.23630572855472565, + 0.03962840512394905, + -0.031759195029735565 + ] + }, + { + "id": "/en/coast_guard_2002", + "initial_release_date": "2002-11-14", + "name": "The Coast Guard", + "directed_by": [ + "Kim Ki-duk" + ], + "genre": [ + "Action Film", + "War film", + "East Asian cinema", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.40934282541275024, + 0.08122441917657852, + 0.022257326170802116, + 0.10463465005159378, + -0.11630769073963165, + -0.29418742656707764, + -0.10828365385532379, + -0.10395918041467667, + -0.02455313503742218, + -0.20890381932258606 + ] + }, + { + "id": "/en/code_46", + "initial_release_date": "2004-05-07", + "name": "Code 46", + "directed_by": [ + "Michael Winterbottom" + ], + "genre": [ + "Science Fiction", + "Thriller", + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.3823948800563812, + -0.19819918274879456, + -0.19408971071243286, + -0.001348039135336876, + 0.1196284219622612, + 0.010471153073012829, + -0.04113464057445526, + -0.1295251101255417, + 0.05579223856329918, + -0.12314105033874512 + ] + }, + { + "id": "/en/codename_kids_next_door_operation_z_e_r_o", + "initial_release_date": "2006-01-13", + "name": "Codename: Kids Next Door: Operation Z.E.R.O.", + "directed_by": [ + "Tom Warburton" + ], + "genre": [ + "Science Fiction", + "Animation", + "Adventure Film", + "Family", + "Comedy", + "Crime Fiction" + ], + "film_vector": [ + -0.1427929699420929, + -0.22029989957809448, + -0.07323699444532394, + 0.2919389307498932, + 0.024034734815359116, + 0.055601567029953, + -0.05416567996144295, + -0.17732027173042297, + 0.01678990013897419, + -0.07478795200586319 + ] + }, + { + "id": "/en/coffee_and_cigarettes", + "initial_release_date": "2003-09-05", + "name": "Coffee and Cigarettes", + "directed_by": [ + "Jim Jarmusch" + ], + "genre": [ + "Music", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.12339229136705399, + 0.12487325072288513, + -0.3159053325653076, + -0.026059646159410477, + -0.329902708530426, + 0.09244094789028168, + 0.043857358396053314, + -0.11371606588363647, + 0.2214530110359192, + -0.0833030641078949 + ] + }, + { + "id": "/en/cold_creek_manor", + "initial_release_date": "2003-09-19", + "name": "Cold Creek Manor", + "directed_by": [ + "Mike Figgis" + ], + "genre": [ + "Thriller", + "Mystery", + "Psychological thriller", + "Crime Thriller", + "Drama" + ], + "film_vector": [ + -0.46716269850730896, + -0.3202633857727051, + -0.33666524291038513, + -0.05548524484038353, + -0.03736110031604767, + 0.03098054975271225, + -0.025136949494481087, + -0.09419646859169006, + 0.07705967128276825, + -0.04018446058034897 + ] + }, + { + "id": "/en/cold_mountain", + "initial_release_date": "2003-12-25", + "name": "Cold Mountain", + "directed_by": [ + "Anthony Minghella" + ], + "genre": [ + "War film", + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.29614725708961487, + -0.024312341585755348, + -0.1933363527059555, + 0.08516436815261841, + 0.18190786242485046, + -0.22175848484039307, + -0.1830754578113556, + -0.1370614618062973, + -0.005989354103803635, + -0.1823120415210724 + ] + }, + { + "id": "/en/cold_showers", + "initial_release_date": "2005-05-22", + "name": "Cold Showers", + "directed_by": [ + "Antony Cordier" + ], + "genre": [ + "Coming of age", + "LGBT", + "World cinema", + "Gay Themed", + "Teen film", + "Erotic Drama", + "Drama" + ], + "film_vector": [ + -0.2881791591644287, + 0.09660360217094421, + -0.27694961428642273, + -0.021722203120589256, + -0.16999000310897827, + -0.02350492961704731, + -0.0726599395275116, + -0.029071828350424767, + 0.35280489921569824, + -0.042395077645778656 + ] + }, + { + "id": "/en/collateral", + "initial_release_date": "2004-08-05", + "name": "Collateral", + "directed_by": [ + "Michael Mann" + ], + "genre": [ + "Thriller", + "Crime Fiction", + "Crime Thriller", + "Film noir", + "Drama" + ], + "film_vector": [ + -0.6109217405319214, + -0.2877897024154663, + -0.3182058334350586, + -0.20888522267341614, + -0.11011605709791183, + -0.1361498236656189, + -0.0032664486207067966, + -0.03074611723423004, + -0.0359954833984375, + -0.03951742500066757 + ] + }, + { + "id": "/en/collateral_damage_2002", + "initial_release_date": "2002-02-04", + "name": "Collateral Damage", + "directed_by": [ + "Andrew Davis" + ], + "genre": [ + "Action Film", + "Thriller", + "Drama" + ], + "film_vector": [ + -0.22136090695858002, + -0.23053976893424988, + -0.12234261631965637, + -0.04981619864702225, + 0.21952131390571594, + -0.20651814341545105, + -0.04725770652294159, + -0.19010749459266663, + -0.026631569489836693, + 0.02742672711610794 + ] + }, + { + "id": "/en/comedian_2002", + "initial_release_date": "2002-10-11", + "name": "Comedian", + "directed_by": [ + "Christian Charles" + ], + "genre": [ + "Indie film", + "Documentary film", + "Stand-up comedy", + "Comedy", + "Biographical film" + ], + "film_vector": [ + -0.20088529586791992, + 0.04967573285102844, + -0.4561716914176941, + 0.003389814868569374, + -0.23358143866062164, + -0.4911760687828064, + 0.13291700184345245, + -0.09418397396802902, + 0.07026556134223938, + -0.14258787035942078 + ] + }, + { + "id": "/en/coming_out_2006", + "name": "Coming Out", + "directed_by": [ + "Joel Zwick" + ], + "genre": [ + "Comedy", + "Drama" + ], + "film_vector": [ + -0.16087505221366882, + 0.05543652921915054, + -0.4770810604095459, + -0.06053946167230606, + -0.13922427594661713, + 0.02967236563563347, + 0.028485115617513657, + -0.18408820033073425, + 0.23361431062221527, + -0.021804075688123703 + ] + }, + { + "id": "/en/commitments", + "initial_release_date": "2001-05-04", + "name": "Commitments", + "directed_by": [ + "Carol Mayes" + ], + "genre": [ + "Romantic comedy", + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.4470764100551605, + 0.10680566728115082, + -0.3667098879814148, + -0.01006869226694107, + 0.1424005925655365, + 0.028963368386030197, + -0.08728522062301636, + -0.18124690651893616, + 0.08380483835935593, + -0.05216178297996521 + ] + }, + { + "id": "/en/common_ground_2000", + "initial_release_date": "2000-01-29", + "name": "Common Ground", + "directed_by": [ + "Donna Deitch" + ], + "genre": [ + "LGBT", + "Drama" + ], + "film_vector": [ + 0.10682182013988495, + 0.12262088805437088, + -0.30187973380088806, + -0.21820785105228424, + -0.027856620028614998, + 0.16177071630954742, + -0.1259315013885498, + -0.013910277746617794, + 0.1992437094449997, + 0.026941031217575073 + ] + }, + { + "id": "/en/company_2002", + "initial_release_date": "2002-04-15", + "name": "Company", + "directed_by": [ + "Ram Gopal Varma" + ], + "genre": [ + "Thriller", + "Action Film", + "Crime Fiction", + "Bollywood", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.6674262285232544, + 0.05401809141039848, + -0.10814562439918518, + -0.029739949852228165, + -0.06556864082813263, + -0.06170794740319252, + 0.0860934853553772, + -0.18598464131355286, + -0.022096015512943268, + -0.07636933028697968 + ] + }, + { + "id": "/en/confessions_of_a_dangerous_mind", + "name": "Confessions of a Dangerous Mind", + "directed_by": [ + "George Clooney" + ], + "genre": [ + "Biographical film", + "Thriller", + "Crime Fiction", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.3269394636154175, + -0.26913756132125854, + -0.1900792121887207, + -0.15605801343917847, + 0.10164454579353333, + -0.21170300245285034, + 0.025736594572663307, + -0.024187104776501656, + 0.04843300208449364, + -0.21194680035114288 + ] + }, + { + "id": "/en/confessions_of_a_teenage_drama_queen", + "initial_release_date": "2004-02-17", + "genre": [ + "Family", + "Teen film", + "Musical comedy", + "Romantic comedy" + ], + "directed_by": [ + "Sara Sugarman" + ], + "name": "Confessions of a Teenage Drama Queen", + "film_vector": [ + -0.21236097812652588, + -0.011002667248249054, + -0.56969153881073, + 0.08521873503923416, + 0.04495104029774666, + -0.0166240893304348, + -0.1113404631614685, + -0.08116034418344498, + 0.23192214965820312, + -0.055839940905570984 + ] + }, + { + "id": "/en/confetti_2006", + "initial_release_date": "2006-05-05", + "genre": [ + "Mockumentary", + "Romantic comedy", + "Romance Film", + "Parody", + "Music", + "Comedy" + ], + "directed_by": [ + "Debbie Isitt" + ], + "name": "Confetti", + "film_vector": [ + -0.12797284126281738, + 0.0809490978717804, + -0.5159974098205566, + 0.014703430235385895, + -0.03018105775117874, + -0.23836632072925568, + 0.08705481886863708, + 0.1307409107685089, + 0.07675494253635406, + 0.027437686920166016 + ] + }, + { + "id": "/en/confidence_2004", + "initial_release_date": "2003-01-20", + "genre": [ + "Thriller", + "Crime Fiction", + "Drama" + ], + "directed_by": [ + "James Foley" + ], + "name": "Confidence", + "film_vector": [ + -0.6072748303413391, + -0.2110082507133484, + -0.2929103970527649, + -0.20419609546661377, + -0.02962654083967209, + 0.07651931047439575, + 0.05865684151649475, + -0.15402628481388092, + 0.12573818862438202, + -0.19350573420524597 + ] + }, + { + "id": "/en/connie_and_carla", + "initial_release_date": "2004-04-16", + "genre": [ + "LGBT", + "Buddy film", + "Comedy of Errors", + "Comedy" + ], + "directed_by": [ + "Michael Lembeck" + ], + "name": "Connie and Carla", + "film_vector": [ + 0.19491271674633026, + 0.06552909314632416, + -0.462568461894989, + 0.10563963651657104, + 0.049099355936050415, + -0.16410362720489502, + 0.08783315122127533, + -0.03987201303243637, + 0.054746244102716446, + -0.21985016763210297 + ] + }, + { + "id": "/en/conspiracy_2001", + "initial_release_date": "2001-05-19", + "genre": [ + "History", + "War film", + "Political drama", + "Historical period drama", + "Drama" + ], + "directed_by": [ + "Frank Pierson" + ], + "name": "Conspiracy", + "film_vector": [ + -0.2992197275161743, + 0.027955688536167145, + -0.021005529910326004, + -0.3116169571876526, + -0.17600873112678528, + -0.11024782061576843, + -0.15004406869411469, + 0.1576397866010666, + -0.07427342236042023, + -0.3092830777168274 + ] + }, + { + "id": "/en/constantine_2005", + "initial_release_date": "2005-02-08", + "genre": [ + "Horror", + "Fantasy", + "Action Film" + ], + "directed_by": [ + "Francis Lawrence" + ], + "name": "Constantine", + "film_vector": [ + -0.2599359154701233, + -0.224975124001503, + -0.03305167332291603, + 0.13699771463871002, + 0.18924929201602936, + -0.05922544002532959, + -0.05533812940120697, + 0.032831598073244095, + 0.012354240752756596, + -0.2265598624944687 + ] + }, + { + "id": "/en/control_room", + "genre": [ + "Documentary film", + "Political cinema", + "Culture & Society", + "War film", + "Journalism", + "Media studies" + ], + "directed_by": [ + "Jehane Noujaim" + ], + "name": "Control Room", + "film_vector": [ + -0.37390410900115967, + 0.07923897355794907, + -0.006923728622496128, + -0.18443390727043152, + -0.25843408703804016, + -0.38241785764694214, + -0.07652597874403, + -0.02448469214141369, + 0.258922278881073, + -0.11369257420301437 + ] + }, + { + "id": "/en/control_the_ian_curtis_film", + "initial_release_date": "2007-05-17", + "genre": [ + "Biographical film", + "Indie film", + "Musical", + "Japanese Movies", + "Drama", + "Musical Drama" + ], + "directed_by": [ + "Anton Corbijn" + ], + "name": "Control", + "film_vector": [ + -0.4463444948196411, + 0.12760642170906067, + -0.2186436951160431, + 0.023019056767225266, + -0.13663366436958313, + -0.20754966139793396, + -0.11302781105041504, + 0.02076905593276024, + 0.20401442050933838, + -0.05771918594837189 + ] + }, + { + "id": "/en/cope_2005", + "initial_release_date": "2007-01-23", + "genre": [ + "Horror", + "B movie" + ], + "directed_by": [ + "Ronald Jackson", + "Ronald Jerry" + ], + "name": "Cope", + "film_vector": [ + -0.1512255072593689, + -0.23805662989616394, + -0.13760314881801605, + 0.14242121577262878, + 0.31264954805374146, + -0.1768510639667511, + 0.1774456650018692, + 0.015782352536916733, + 0.14009526371955872, + -0.08941879868507385 + ] + }, + { + "id": "/en/copying_beethoven", + "initial_release_date": "2006-07-30", + "genre": [ + "Biographical film", + "Music", + "Historical fiction", + "Drama" + ], + "directed_by": [ + "Agnieszka Holland" + ], + "name": "Copying Beethoven", + "film_vector": [ + -0.13600346446037292, + 0.10992667078971863, + 0.046708084642887115, + -0.10999225825071335, + -0.12166238576173782, + -0.16849596798419952, + -0.09929583966732025, + 0.045679718255996704, + 0.061162352561950684, + -0.22318589687347412 + ] + }, + { + "id": "/en/corporate", + "initial_release_date": "2006-07-07", + "genre": [ + "Drama" + ], + "directed_by": [ + "Madhur Bhandarkar" + ], + "name": "Corporate", + "film_vector": [ + 0.12006571888923645, + -0.0019329872447997332, + -0.06178031861782074, + -0.2934531569480896, + -0.004395443946123123, + 0.14401812851428986, + -0.06436511874198914, + -0.03265857696533203, + -0.0910830944776535, + 0.1026117205619812 + ] + }, + { + "id": "/en/corpse_bride", + "initial_release_date": "2005-09-07", + "genre": [ + "Fantasy", + "Animation", + "Musical", + "Romance Film" + ], + "directed_by": [ + "Tim Burton", + "Mike Johnson" + ], + "name": "Corpse Bride", + "film_vector": [ + -0.35123634338378906, + -0.005872692912817001, + -0.21058005094528198, + 0.2749534249305725, + 0.09434380382299423, + -0.07116107642650604, + 0.04743753373622894, + 0.13831458985805511, + 0.15588650107383728, + -0.19408418238162994 + ] + }, + { + "id": "/en/covert_one_the_hades_factor", + "genre": [ + "Thriller", + "Action Film", + "Action/Adventure" + ], + "directed_by": [ + "Mick Jackson" + ], + "name": "Covert One: The Hades Factor", + "film_vector": [ + -0.3020648658275604, + -0.33378005027770996, + -0.04770423471927643, + -0.017137184739112854, + 0.25078245997428894, + -0.09375472366809845, + -0.027366016060113907, + -0.09903953224420547, + -0.033802278339862823, + -0.07688207924365997 + ] + }, + { + "id": "/en/cow_belles", + "initial_release_date": "2006-03-24", + "genre": [ + "Family", + "Television film", + "Teen film", + "Romantic comedy", + "Comedy" + ], + "directed_by": [ + "Francine McDougall" + ], + "name": "Cow Belles", + "film_vector": [ + 0.026301797479391098, + 0.07857741415500641, + -0.34646177291870117, + 0.26839977502822876, + 0.1274135410785675, + -0.06128157675266266, + -0.026231549680233, + -0.10483622550964355, + 0.06655946373939514, + -0.13863855600357056 + ] + }, + { + "id": "/en/cowards_bend_the_knee", + "initial_release_date": "2003-02-26", + "genre": [ + "Silent film", + "Indie film", + "Surrealism", + "Romance Film", + "Experimental film", + "Crime Fiction", + "Avant-garde", + "Drama" + ], + "directed_by": [ + "Guy Maddin" + ], + "name": "Cowards Bend the Knee", + "film_vector": [ + -0.44136691093444824, + 0.0648161768913269, + -0.1821441948413849, + -0.059985946863889694, + -0.2563510835170746, + -0.3390137851238251, + -0.03236473351716995, + -0.04251180961728096, + 0.21364304423332214, + -0.25444406270980835 + ] + }, + { + "id": "/en/cowboy_bebop_the_movie", + "initial_release_date": "2001-09-01", + "genre": [ + "Anime", + "Science Fiction", + "Action Film", + "Animation", + "Comedy", + "Crime Fiction" + ], + "directed_by": [ + "Shinichir\u014d Watanabe" + ], + "name": "Cowboy Bebop: The Movie", + "film_vector": [ + -0.23655089735984802, + -0.004660226404666901, + -0.0742921233177185, + 0.34333184361457825, + -0.2253463864326477, + -0.1350008249282837, + -0.07074077427387238, + -0.14019779860973358, + -0.04403857886791229, + -0.12813840806484222 + ] + }, + { + "id": "/en/coyote_ugly", + "initial_release_date": "2000-07-31", + "genre": [ + "Musical", + "Romance Film", + "Comedy", + "Drama", + "Musical comedy", + "Musical Drama" + ], + "directed_by": [ + "David McNally" + ], + "name": "Coyote Ugly", + "film_vector": [ + -0.25143593549728394, + -0.005267959088087082, + -0.5557999610900879, + 0.11723394691944122, + -0.0755058005452156, + -0.18217132985591888, + -0.13763590157032013, + 0.09474768489599228, + -0.03551054745912552, + 0.0356891006231308 + ] + }, + { + "id": "/en/crackerjack_2002", + "initial_release_date": "2002-11-07", + "genre": [ + "Comedy" + ], + "directed_by": [ + "Paul Moloney" + ], + "name": "Crackerjack", + "film_vector": [ + 0.18719112873077393, + -0.0815492644906044, + -0.2929527163505554, + 0.05470184236764908, + -0.06672725081443787, + -0.14751936495304108, + 0.34087446331977844, + -0.1201971098780632, + -0.10910852253437042, + -0.09258968383073807 + ] + }, + { + "id": "/en/cradle_2_the_grave", + "initial_release_date": "2003-02-28", + "genre": [ + "Martial Arts Film", + "Thriller", + "Action Film", + "Crime Fiction", + "Buddy film", + "Action Thriller", + "Adventure Film", + "Crime" + ], + "directed_by": [ + "Andrzej Bartkowiak" + ], + "name": "Cradle 2 the Grave", + "film_vector": [ + -0.41003650426864624, + -0.24417348206043243, + -0.24374346435070038, + 0.12818440794944763, + 0.09702645242214203, + -0.21336182951927185, + -0.008994477801024914, + 0.05345335975289345, + -0.023484744131565094, + 0.028746452182531357 + ] + }, + { + "id": "/en/cradle_of_fear", + "genre": [ + "Horror", + "B movie", + "Slasher" + ], + "directed_by": [ + "Alex Chandon" + ], + "name": "Cradle of Fear", + "film_vector": [ + -0.27585381269454956, + -0.3818672001361847, + -0.07786525785923004, + 0.1794818639755249, + 0.2028072625398636, + -0.1470005363225937, + 0.1904790699481964, + 0.06291869282722473, + 0.196730375289917, + -0.06195797398686409 + ] + }, + { + "id": "/en/crank", + "initial_release_date": "2006-08-31", + "genre": [ + "Thriller", + "Action Film", + "Action/Adventure", + "Crime Thriller", + "Crime Fiction", + "Action Thriller" + ], + "directed_by": [ + "Neveldine/Taylor" + ], + "name": "Crank", + "film_vector": [ + -0.5971211194992065, + -0.35031989216804504, + -0.31827735900878906, + 0.019908739253878593, + -0.11041117459535599, + -0.12422779947519302, + -0.033986106514930725, + -0.04343710467219353, + -0.12655749917030334, + 0.014740467071533203 + ] + }, + { + "id": "/en/crash_2004", + "initial_release_date": "2004-09-10", + "genre": [ + "Crime Fiction", + "Indie film", + "Drama" + ], + "directed_by": [ + "Paul Haggis" + ], + "name": "Crash", + "film_vector": [ + -0.4080565273761749, + -0.22253049910068512, + -0.22678431868553162, + -0.1474086344242096, + -0.0008448250591754913, + -0.14564023911952972, + 0.0006831586360931396, + -0.26911380887031555, + 0.15552707016468048, + -0.08955936133861542 + ] + }, + { + "id": "/en/crazy_beautiful", + "initial_release_date": "2001-06-28", + "genre": [ + "Teen film", + "Romance Film", + "Drama" + ], + "directed_by": [ + "John Stockwell" + ], + "name": "Crazy/Beautiful", + "film_vector": [ + -0.4720912575721741, + -0.013477090746164322, + -0.40101197361946106, + 0.1683369278907776, + 0.19344863295555115, + -0.06939215958118439, + -0.08351808041334152, + -0.13829132914543152, + 0.27441108226776123, + -0.06168648600578308 + ] + }, + { + "id": "/en/creep_2005", + "initial_release_date": "2004-08-10", + "genre": [ + "Horror", + "Mystery", + "Thriller" + ], + "directed_by": [ + "Christopher Smith" + ], + "name": "Creep", + "film_vector": [ + -0.5164979100227356, + -0.43986108899116516, + -0.2531401515007019, + 0.009687520563602448, + 0.0045545510947704315, + 0.028289122506976128, + 0.2590848505496979, + 0.05833469331264496, + 0.18096394836902618, + -0.09193211793899536 + ] + }, + { + "id": "/en/criminal", + "initial_release_date": "2004-09-10", + "genre": [ + "Thriller", + "Crime Fiction", + "Indie film", + "Crime Thriller", + "Heist film", + "Comedy", + "Drama" + ], + "directed_by": [ + "Gregory Jacobs" + ], + "name": "Criminal", + "film_vector": [ + -0.6389719247817993, + -0.2901425361633301, + -0.4108043313026428, + -0.05855589732527733, + -0.14959931373596191, + -0.17590749263763428, + 0.032696258276700974, + -0.11771260201931, + -0.009840073063969612, + -0.041770197451114655 + ] + }, + { + "id": "/en/crimson_gold", + "genre": [ + "World cinema", + "Thriller", + "Drama" + ], + "directed_by": [ + "Jafar Panahi" + ], + "name": "Crimson Gold", + "film_vector": [ + -0.37829431891441345, + -0.011746632866561413, + -0.041373882442712784, + -0.07736489176750183, + 0.10461869835853577, + -0.11262091249227524, + -0.022351667284965515, + -0.07169660925865173, + 0.11962516605854034, + -0.19958162307739258 + ] + }, + { + "id": "/en/crimson_rivers_ii_angels_of_the_apocalypse", + "initial_release_date": "2004-02-18", + "genre": [ + "Action Film", + "Thriller", + "Crime Fiction" + ], + "directed_by": [ + "Olivier Dahan" + ], + "name": "Crimson Rivers II: Angels of the Apocalypse", + "film_vector": [ + -0.2989763617515564, + -0.3193380832672119, + -0.061119914054870605, + 0.018223945051431656, + 0.20580178499221802, + -0.19345664978027344, + -0.11779086291790009, + -0.06044747680425644, + -0.009767284616827965, + -0.08148461580276489 + ] + }, + { + "id": "/en/crocodile_2000", + "initial_release_date": "2000-12-26", + "genre": [ + "Horror", + "Natural horror film", + "Teen film", + "Thriller", + "Action Film", + "Action/Adventure" + ], + "directed_by": [ + "Tobe Hooper" + ], + "name": "Crocodile", + "film_vector": [ + -0.5144491195678711, + -0.23265933990478516, + -0.1796778440475464, + 0.3426196873188019, + -0.01870694011449814, + -0.14867353439331055, + 0.014535665512084961, + 0.018885809928178787, + 0.09075117111206055, + 0.011337787844240665 + ] + }, + { + "id": "/en/crocodile_2_death_swamp", + "initial_release_date": "2002-08-01", + "genre": [ + "Horror", + "Natural horror film", + "B movie", + "Action/Adventure", + "Action Film", + "Thriller", + "Adventure Film", + "Action Thriller", + "Creature Film" + ], + "directed_by": [ + "Gary Jones" + ], + "name": "Crocodile 2: Death Swamp", + "film_vector": [ + -0.3267671465873718, + -0.1839211881160736, + -0.1207435131072998, + 0.28898757696151733, + 0.027120551094412804, + -0.2629541754722595, + -0.013869590125977993, + 0.1850045919418335, + -0.1164320558309555, + 0.06386163085699081 + ] + }, + { + "id": "/en/crocodile_dundee_in_los_angeles", + "initial_release_date": "2001-04-12", + "genre": [ + "Action Film", + "Adventure Film", + "Action/Adventure", + "World cinema", + "Action Comedy", + "Comedy", + "Drama" + ], + "directed_by": [ + "Simon Wincer" + ], + "name": "Crocodile Dundee in Los Angeles", + "film_vector": [ + -0.24961385130882263, + -0.052176978439092636, + -0.14249393343925476, + 0.16716724634170532, + -0.08210782706737518, + -0.3557916283607483, + -0.06761011481285095, + 0.017583368346095085, + -0.16470038890838623, + -0.062474027276039124 + ] + }, + { + "id": "/en/crossing_the_bridge_the_sound_of_istanbul", + "initial_release_date": "2005-06-09", + "genre": [ + "Musical", + "Documentary film", + "Music", + "Culture & Society" + ], + "directed_by": [ + "Fatih Ak\u0131n" + ], + "name": "Crossing the Bridge: The Sound of Istanbul", + "film_vector": [ + -0.101036936044693, + 0.24070683121681213, + -0.023111892864108086, + -0.17356739938259125, + -0.05988437682390213, + -0.2480141818523407, + -0.10464516282081604, + 0.1583307683467865, + 0.23270922899246216, + -0.08918379247188568 + ] + }, + { + "id": "/en/crossover_2006", + "initial_release_date": "2006-09-01", + "genre": [ + "Action Film", + "Coming of age", + "Teen film", + "Sports", + "Short Film", + "Fantasy", + "Drama" + ], + "directed_by": [ + "Preston A. Whitmore II" + ], + "name": "Crossover", + "film_vector": [ + -0.4882286489009857, + 0.013875514268875122, + -0.31992751359939575, + 0.21229225397109985, + -0.22295284271240234, + -0.11181559413671494, + -0.18157996237277985, + -0.18087071180343628, + 0.19297927618026733, + -0.010383740067481995 + ] + }, + { + "id": "/en/crossroads_2002", + "initial_release_date": "2002-02-11", + "genre": [ + "Coming of age", + "Teen film", + "Musical", + "Romance Film", + "Romantic comedy", + "Adventure Film", + "Comedy-drama", + "Musical Drama", + "Musical comedy", + "Comedy", + "Drama" + ], + "directed_by": [ + "Tamra Davis" + ], + "name": "Crossroads", + "film_vector": [ + -0.37776628136634827, + 0.015496015548706055, + -0.5634211301803589, + 0.11346211284399033, + -0.0832735225558281, + -0.15963244438171387, + -0.22159729897975922, + 0.16652682423591614, + 0.043688494712114334, + 0.09096607565879822 + ] + }, + { + "id": "/en/crouching_tiger_hidden_dragon", + "initial_release_date": "2000-05-16", + "genre": [ + "Romance Film", + "Action Film", + "Martial Arts Film", + "Drama" + ], + "directed_by": [ + "Ang Lee" + ], + "name": "Crouching Tiger, Hidden Dragon", + "film_vector": [ + -0.5478194952011108, + 0.08508278429508209, + -0.16754865646362305, + 0.2774726152420044, + -0.0236420389264822, + -0.1708419770002365, + -0.16159960627555847, + -0.08014045655727386, + -0.061950936913490295, + -0.10223536193370819 + ] + }, + { + "id": "/en/cruel_intentions_3", + "initial_release_date": "2004-05-25", + "genre": [ + "Erotica", + "Thriller", + "Teen film", + "Psychological thriller", + "Romance Film", + "Erotic thriller", + "Crime Fiction", + "Crime Thriller", + "Drama" + ], + "directed_by": [ + "Scott Ziehl" + ], + "name": "Cruel Intentions 3", + "film_vector": [ + -0.5097483396530151, + -0.24726425111293793, + -0.3597763180732727, + -0.03957739844918251, + 0.10876208543777466, + -0.09281586110591888, + -0.08177599310874939, + 0.1528887152671814, + 0.027378126978874207, + 0.031469251960515976 + ] + }, + { + "id": "/en/crustaces_et_coquillages", + "initial_release_date": "2005-02-12", + "genre": [ + "Musical", + "Romantic comedy", + "LGBT", + "Romance Film", + "World cinema", + "Musical Drama", + "Musical comedy", + "Comedy", + "Drama" + ], + "directed_by": [ + "Jacques Martineau", + "Olivier Ducastel" + ], + "name": "Crustac\u00e9s et Coquillages", + "film_vector": [ + -0.2064996361732483, + 0.13901539146900177, + -0.34505441784858704, + 0.07424800097942352, + -0.10083014518022537, + -0.11951218545436859, + -0.06538847833871841, + 0.3171536922454834, + 0.15137341618537903, + -0.04777415469288826 + ] + }, + { + "id": "/en/cry_wolf", + "initial_release_date": "2005-09-16", + "genre": [ + "Slasher", + "Horror", + "Mystery", + "Thriller", + "Drama" + ], + "directed_by": [ + "Jeff Wadlow" + ], + "name": "Cry_Wolf", + "film_vector": [ + -0.4836834669113159, + -0.38584885001182556, + -0.20179378986358643, + 0.012357071042060852, + -0.05678654462099075, + 0.08432323485612869, + 0.11562366783618927, + 0.05429135635495186, + 0.0942409560084343, + -0.01772230863571167 + ] + }, + { + "id": "/en/cube_2_hypercube", + "initial_release_date": "2002-04-15", + "genre": [ + "Science Fiction", + "Horror", + "Psychological thriller", + "Thriller", + "Escape Film" + ], + "directed_by": [ + "Andrzej Seku\u0142a" + ], + "name": "Cube 2: Hypercube", + "film_vector": [ + -0.24040891230106354, + -0.2907794713973999, + -0.03600326552987099, + 0.12269239127635956, + 0.24428075551986694, + -0.11926324665546417, + 0.05490382760763168, + -0.07197318226099014, + 0.06390848755836487, + 0.04898575693368912 + ] + }, + { + "id": "/en/curious_george_2006", + "initial_release_date": "2006-02-10", + "genre": [ + "Animation", + "Adventure Film", + "Family", + "Comedy" + ], + "directed_by": [ + "Matthew O'Callaghan" + ], + "name": "Curious George", + "film_vector": [ + -0.02158758044242859, + 0.0205291248857975, + -0.16788309812545776, + 0.5126817226409912, + -0.16445903480052948, + -0.07196798920631409, + -0.11644509434700012, + -0.10549869388341904, + 0.10108719766139984, + -0.25787511467933655 + ] + }, + { + "id": "/en/curse_of_the_golden_flower", + "initial_release_date": "2006-12-21", + "genre": [ + "Romance Film", + "Action Film", + "Drama" + ], + "directed_by": [ + "Zhang Yimou" + ], + "name": "Curse of the Golden Flower", + "film_vector": [ + -0.3636570870876312, + 0.07603482902050018, + -0.2243317812681198, + 0.11328905820846558, + 0.29302626848220825, + -0.05010753870010376, + -0.10107302665710449, + 0.09477971494197845, + 0.039989978075027466, + -0.20763806998729706 + ] + }, + { + "id": "/en/cursed", + "initial_release_date": "2004-11-07", + "genre": [ + "Horror", + "Thriller", + "Horror comedy", + "Comedy" + ], + "directed_by": [ + "Wes Craven" + ], + "name": "Cursed", + "film_vector": [ + -0.4318277835845947, + -0.2618894577026367, + -0.34079957008361816, + 0.06662562489509583, + -0.08934960514307022, + -0.04089754819869995, + 0.2754228711128235, + 0.1825345754623413, + 0.07522856444120407, + -0.14365990459918976 + ] + }, + { + "id": "/en/d-tox", + "initial_release_date": "2002-01-04", + "genre": [ + "Thriller", + "Crime Thriller", + "Horror", + "Mystery" + ], + "directed_by": [ + "Jim Gillespie" + ], + "name": "D-Tox", + "film_vector": [ + -0.5062456130981445, + -0.39777880907058716, + -0.20683911442756653, + 0.042709432542324066, + -0.03529665991663933, + 0.017969923093914986, + 0.1197924017906189, + -0.06802349537611008, + 0.06591780483722687, + -0.05200637876987457 + ] + }, + { + "id": "/en/daddy", + "initial_release_date": "2001-10-04", + "genre": [ + "Family", + "Drama", + "Tollywood", + "World cinema" + ], + "directed_by": [ + "Suresh Krissna" + ], + "name": "Daddy", + "film_vector": [ + -0.4967193007469177, + 0.36937734484672546, + -0.12742283940315247, + 0.03251279145479202, + -0.10806017369031906, + -0.06689861416816711, + 0.10748355090618134, + -0.16897565126419067, + 0.10715553164482117, + -0.08606815338134766 + ] + }, + { + "id": "/en/daddy_day_care", + "initial_release_date": "2003-05-04", + "genre": [ + "Family", + "Comedy" + ], + "directed_by": [ + "Steve Carr" + ], + "name": "Daddy Day Care", + "film_vector": [ + 0.21632207930088043, + 0.054531633853912354, + -0.3642280697822571, + 0.16969779133796692, + 0.0077271899208426476, + -0.017700014635920525, + 0.14809557795524597, + -0.17585916817188263, + 0.05103803798556328, + -0.12139324843883514 + ] + }, + { + "id": "/en/daddy_long-legs", + "initial_release_date": "2005-01-13", + "genre": [ + "Romantic comedy", + "East Asian cinema", + "World cinema", + "Drama" + ], + "directed_by": [ + "Gong Jeong-shik" + ], + "name": "Daddy-Long-Legs", + "film_vector": [ + -0.37089258432388306, + 0.29162371158599854, + -0.23805218935012817, + 0.11868631839752197, + 0.015271115116775036, + -0.14953331649303436, + 0.0526847243309021, + -0.0756005123257637, + 0.13193371891975403, + -0.2586919665336609 + ] + }, + { + "id": "/en/dahmer_2002", + "initial_release_date": "2002-06-21", + "genre": [ + "Thriller", + "Biographical film", + "LGBT", + "Crime Fiction", + "Indie film", + "Mystery", + "Cult film", + "Horror", + "Slasher", + "Drama" + ], + "directed_by": [ + "David Jacobson" + ], + "name": "Dahmer", + "film_vector": [ + -0.5313695669174194, + -0.3423272967338562, + -0.2753787934780121, + -0.036816637963056564, + -0.08078563213348389, + -0.20638640224933624, + 0.025681355968117714, + -0.10553644597530365, + 0.035793714225292206, + -0.08061240613460541 + ] + }, + { + "id": "/en/daisy_2006", + "initial_release_date": "2006-03-09", + "genre": [ + "Chinese Movies", + "Romance Film", + "Melodrama", + "Drama" + ], + "directed_by": [ + "Andrew Lau" + ], + "name": "Daisy", + "film_vector": [ + -0.3405252993106842, + 0.21508878469467163, + -0.27299875020980835, + 0.07569859176874161, + 0.24582277238368988, + -0.07879501581192017, + -0.036025237292051315, + -0.04523072391748428, + 0.12053515017032623, + -0.19347216188907623 + ] + }, + { + "id": "/en/daivanamathil", + "genre": [ + "Drama", + "Malayalam Cinema", + "World cinema" + ], + "directed_by": [ + "Jayaraj" + ], + "name": "Daivanamathil", + "film_vector": [ + -0.5155149698257446, + 0.41707155108451843, + 0.0667664110660553, + -0.032923225313425064, + -0.03953384608030319, + -0.08399057388305664, + 0.11624473333358765, + -0.022075394168496132, + 0.06361337751150131, + -0.1085720881819725 + ] + }, + { + "id": "/en/daltry_calhoun", + "initial_release_date": "2005-09-25", + "genre": [ + "Black comedy", + "Comedy-drama", + "Comedy", + "Drama" + ], + "directed_by": [ + "Katrina Holden Bronson" + ], + "name": "Daltry Calhoun", + "film_vector": [ + 0.07401268929243088, + 0.06940226256847382, + -0.38168981671333313, + -0.15856441855430603, + -0.07247962802648544, + -0.08618641644716263, + 0.1350027620792389, + -0.007628841325640678, + -0.09064913541078568, + -0.27809497714042664 + ] + }, + { + "id": "/en/dan_in_real_life", + "initial_release_date": "2007-10-26", + "genre": [ + "Romance Film", + "Romantic comedy", + "Comedy-drama", + "Domestic Comedy", + "Comedy", + "Drama" + ], + "directed_by": [ + "Peter Hedges" + ], + "name": "Dan in Real Life", + "film_vector": [ + -0.18344277143478394, + 0.09092232584953308, + -0.5102387070655823, + -0.0024051330983638763, + -0.10426373779773712, + -0.08849920332431793, + -0.01428186148405075, + -0.10198450088500977, + 0.0009230737341567874, + -0.18402542173862457 + ] + }, + { + "id": "/en/dancer_in_the_dark", + "initial_release_date": "2000-05-17", + "genre": [ + "Musical", + "Crime Fiction", + "Melodrama", + "Drama", + "Musical Drama" + ], + "directed_by": [ + "Lars von Trier" + ], + "name": "Dancer in the Dark", + "film_vector": [ + -0.43672654032707214, + -0.07454868406057358, + -0.3428443670272827, + -0.14641496539115906, + -0.13571852445602417, + 0.011759744957089424, + -0.06029919534921646, + 0.12841880321502686, + 0.14436744153499603, + -0.2250150889158249 + ] + }, + { + "id": "/en/daniel_amos_live_in_anaheim_1985", + "genre": [ + "Music video" + ], + "directed_by": [ + "Dave Perry" + ], + "name": "Daniel Amos Live in Anaheim 1985", + "film_vector": [ + 0.14645974338054657, + -0.011252429336309433, + 0.06216612085700035, + 0.026354871690273285, + 0.10877999663352966, + -0.13772685825824738, + -0.03935426473617554, + -1.922808587551117e-05, + 0.1947573572397232, + 0.14300097525119781 + ] + }, + { + "id": "/en/danny_deckchair", + "genre": [ + "Romantic comedy", + "Indie film", + "Romance Film", + "World cinema", + "Fantasy Comedy", + "Comedy" + ], + "directed_by": [ + "Jeff Balsmeyer" + ], + "name": "Danny Deckchair", + "film_vector": [ + -0.23680153489112854, + 0.08726248890161514, + -0.356534481048584, + 0.13603143393993378, + 0.14864905178546906, + -0.2318568080663681, + 0.014975178986787796, + -0.05009901896119118, + 0.0581282339990139, + -0.19275569915771484 + ] + }, + { + "id": "/en/daredevil_2003", + "initial_release_date": "2003-02-09", + "genre": [ + "Action Film", + "Fantasy", + "Thriller", + "Crime Fiction", + "Superhero movie" + ], + "directed_by": [ + "Mark Steven Johnson" + ], + "name": "Daredevil", + "film_vector": [ + -0.5255327224731445, + -0.2777881622314453, + -0.19420143961906433, + 0.159092515707016, + -0.14787845313549042, + -0.043783076107501984, + -0.10729561746120453, + -0.21942971646785736, + -0.054433196783065796, + -0.032378699630498886 + ] + }, + { + "id": "/en/dark_blue", + "initial_release_date": "2002-12-14", + "genre": [ + "Action Film", + "Crime Fiction", + "Historical period drama", + "Drama" + ], + "directed_by": [ + "Ron Shelton" + ], + "name": "Dark Blue", + "film_vector": [ + -0.5177940130233765, + -0.04841626435518265, + -0.09342733025550842, + -0.10281899571418762, + -0.11889798939228058, + -0.07652928680181503, + -0.06564218550920486, + -0.048752449452877045, + 0.003767864778637886, + -0.32474377751350403 + ] + }, + { + "id": "/en/dark_harvest", + "genre": [ + "Horror", + "Slasher" + ], + "directed_by": [ + "Paul Moore, Jr." + ], + "name": "Dark Harvest", + "film_vector": [ + -0.25462615489959717, + -0.4143006205558777, + 0.07746352255344391, + 0.04673703759908676, + 0.09331779181957245, + -0.005751068703830242, + 0.27675485610961914, + 0.12319952249526978, + 0.13419249653816223, + -0.08776986598968506 + ] + }, + { + "id": "/en/dark_water", + "initial_release_date": "2005-06-27", + "genre": [ + "Thriller", + "Horror", + "Drama" + ], + "directed_by": [ + "Walter Salles" + ], + "name": "Dark Water", + "film_vector": [ + -0.4571418762207031, + -0.29957014322280884, + -0.10010513663291931, + -0.010028056800365448, + 0.10093267261981964, + -0.022278938442468643, + 0.0476854108273983, + 0.03705809265375137, + 0.12082718312740326, + -0.14401689171791077 + ] + }, + { + "id": "/en/dark_water_2002", + "initial_release_date": "2002-01-19", + "genre": [ + "Thriller", + "Horror", + "Mystery", + "Drama" + ], + "directed_by": [ + "Hideo Nakata" + ], + "name": "Dark Water", + "film_vector": [ + -0.5039560794830322, + -0.3232453763484955, + -0.1416063904762268, + 0.0024790652096271515, + 0.03035198152065277, + 0.010500296950340271, + 0.025703705847263336, + 0.051657535135746, + 0.0898720845580101, + -0.1416035294532776 + ] + }, + { + "id": "/en/darkness_2002", + "initial_release_date": "2002-10-03", + "genre": [ + "Horror" + ], + "directed_by": [ + "Jaume Balaguer\u00f3" + ], + "name": "Darkness", + "film_vector": [ + -0.1270793378353119, + -0.3418482840061188, + 0.1041458398103714, + 0.002507692202925682, + 0.11107835173606873, + 0.03192530944943428, + 0.28702524304389954, + 0.2487189918756485, + 0.19012799859046936, + -0.06688462197780609 + ] + }, + { + "id": "/en/darna_mana_hai", + "initial_release_date": "2003-07-25", + "genre": [ + "Horror", + "Adventure Film", + "Bollywood", + "World cinema" + ], + "directed_by": [ + "Prawaal Raman" + ], + "name": "Darna Mana Hai", + "film_vector": [ + -0.5946649312973022, + 0.2842949628829956, + 0.01583828590810299, + 0.1738281100988388, + 0.025373440235853195, + -0.04783250764012337, + 0.1845581829547882, + -0.03802379593253136, + 0.08258740603923798, + -0.0472462996840477 + ] + }, + { + "id": "/en/darna_zaroori_hai", + "initial_release_date": "2006-04-28", + "genre": [ + "Horror", + "Thriller", + "Comedy", + "Bollywood", + "World cinema" + ], + "directed_by": [ + "Ram Gopal Varma", + "Jijy Philip", + "Prawaal Raman", + "Vivek Shah", + "J. D. Chakravarthy", + "Sajid Khan", + "Manish Gupta" + ], + "name": "Darna Zaroori Hai", + "film_vector": [ + -0.5824675559997559, + 0.2461778223514557, + -0.10945335030555725, + 0.08380194008350372, + 0.018150361254811287, + -0.02137215994298458, + 0.2397235631942749, + -0.11313414573669434, + 0.1208340972661972, + -0.05879868566989899 + ] + }, + { + "id": "/en/darth_vaders_psychic_hotline", + "initial_release_date": "2002-04-16", + "genre": [ + "Indie film", + "Short Film", + "Fan film" + ], + "directed_by": [ + "John E. Hudgens" + ], + "name": "Darth Vader's Psychic Hotline", + "film_vector": [ + -0.0868593156337738, + -0.056650519371032715, + -0.12081611156463623, + 0.11436206102371216, + 0.14263248443603516, + -0.2600848078727722, + 0.06094040721654892, + -0.12241363525390625, + 0.05173970013856888, + -0.06999599933624268 + ] + }, + { + "id": "/en/darwins_nightmare", + "initial_release_date": "2004-09-01", + "genre": [ + "Documentary film", + "Political cinema", + "Biographical film" + ], + "directed_by": [ + "Hubert Sauper" + ], + "name": "Darwin's Nightmare", + "film_vector": [ + -0.1192450076341629, + -0.04421687126159668, + 0.09595195204019547, + 0.05138472840189934, + -0.02746903896331787, + -0.3863047957420349, + -0.03666844218969345, + 0.11398007720708847, + 0.2182728350162506, + -0.14241495728492737 + ] + }, + { + "id": "/en/das_experiment", + "initial_release_date": "2010-07-15", + "genre": [ + "Thriller", + "Psychological thriller", + "Drama" + ], + "directed_by": [ + "Paul Scheuring" + ], + "name": "The Experiment", + "film_vector": [ + -0.3759625554084778, + -0.3343404233455658, + -0.18034985661506653, + -0.163437157869339, + 0.03701133653521538, + -0.13322123885154724, + 0.0715075135231018, + 0.09491614252328873, + 0.12918896973133087, + -0.06878463178873062 + ] + }, + { + "id": "/en/dasavatharam", + "initial_release_date": "2008-06-12", + "genre": [ + "Science Fiction", + "Disaster Film", + "Tamil cinema" + ], + "directed_by": [ + "K. S. Ravikumar" + ], + "name": "Dasavathaaram", + "film_vector": [ + -0.3935520648956299, + 0.13705392181873322, + 0.14890867471694946, + 0.02538488432765007, + 0.17287863790988922, + -0.16123740375041962, + 0.10444187372922897, + -0.009553065523505211, + -0.12315458059310913, + 0.025182122364640236 + ] + }, + { + "id": "/en/date_movie", + "initial_release_date": "2006-02-17", + "genre": [ + "Romantic comedy", + "Parody", + "Romance Film", + "Comedy" + ], + "directed_by": [ + "Aaron Seltzer", + "Jason Friedberg" + ], + "name": "Date Movie", + "film_vector": [ + -0.20747798681259155, + 0.10066890716552734, + -0.6253563761711121, + 0.1692419946193695, + 0.11518002301454544, + -0.2078132927417755, + 0.07586226612329483, + 0.04576481133699417, + -0.02358240634202957, + -0.05835724622011185 + ] + }, + { + "id": "/en/dave_attells_insomniac_tour", + "initial_release_date": "2006-04-11", + "genre": [ + "Stand-up comedy", + "Comedy" + ], + "directed_by": [ + "Joel Gallen" + ], + "name": "Dave Attell's Insomniac Tour", + "film_vector": [ + 0.10439871996641159, + -0.05987247824668884, + -0.2147323042154312, + -0.07345040142536163, + -0.1715432107448578, + -0.2043040543794632, + 0.20906412601470947, + -0.011702780611813068, + 0.05062966048717499, + -0.03233737498521805 + ] + }, + { + "id": "/en/dave_chappelles_block_party", + "initial_release_date": "2006-03-03", + "genre": [ + "Documentary film", + "Music", + "Concert film", + "Hip hop film", + "Stand-up comedy", + "Comedy" + ], + "directed_by": [ + "Michel Gondry" + ], + "name": "Dave Chappelle's Block Party", + "film_vector": [ + -0.03555086627602577, + 0.003970302641391754, + -0.3511255383491516, + 0.02851823903620243, + -0.2865520119667053, + -0.41027581691741943, + 0.12623350322246552, + 0.0029071420431137085, + -0.0010844434145838022, + 0.08187738060951233 + ] + }, + { + "id": "/en/david_layla", + "initial_release_date": "2005-10-21", + "genre": [ + "Romantic comedy", + "Indie film", + "Romance Film", + "Comedy-drama", + "Comedy", + "Drama" + ], + "directed_by": [ + "Jay Jonroy" + ], + "name": "David & Layla", + "film_vector": [ + -0.19904404878616333, + 0.0717504546046257, + -0.508625864982605, + 0.008940846659243107, + 0.19006472826004028, + -0.16149470210075378, + -0.10782217979431152, + 0.03224792331457138, + 0.060689687728881836, + -0.0025372121017426252 + ] + }, + { + "id": "/en/david_gilmour_in_concert", + "genre": [ + "Music video", + "Concert film" + ], + "directed_by": [ + "David Mallet" + ], + "name": "David Gilmour in Concert", + "film_vector": [ + 0.04607735201716423, + 0.06524953991174698, + -0.06150342524051666, + -0.026231374591588974, + 0.18979613482952118, + -0.3120063841342926, + -0.05141724273562431, + 0.06306610256433487, + 0.13894936442375183, + 0.0759318396449089 + ] + }, + { + "id": "/en/dawn_of_the_dead_2004", + "initial_release_date": "2004-03-10", + "genre": [ + "Horror", + "Action Film", + "Thriller", + "Science Fiction", + "Drama" + ], + "directed_by": [ + "Zack Snyder" + ], + "name": "Dawn of the Dead", + "film_vector": [ + -0.5132952332496643, + -0.33713483810424805, + -0.1428501009941101, + 0.11496071517467499, + -0.0536542609333992, + -0.1720382571220398, + 0.02732319012284279, + 0.09255409985780716, + 0.09123897552490234, + -0.0903693437576294 + ] + }, + { + "id": "/en/day_of_the_dead_2007", + "initial_release_date": "2008-04-08", + "genre": [ + "Splatter film", + "Doomsday film", + "Horror", + "Thriller", + "Cult film", + "Zombie Film" + ], + "directed_by": [ + "Steve Miner" + ], + "name": "Day of the Dead", + "film_vector": [ + -0.4409291446208954, + -0.33450257778167725, + -0.15342342853546143, + 0.17384687066078186, + 0.0006611291319131851, + -0.34198492765426636, + 0.1110304594039917, + 0.15382394194602966, + 0.02646831050515175, + 0.06887231767177582 + ] + }, + { + "id": "/en/day_of_the_dead_2_contagium", + "initial_release_date": "2005-10-18", + "genre": [ + "Horror", + "Zombie Film" + ], + "directed_by": [ + "Ana Clavell", + "James Glenn Dudelson" + ], + "name": "Day of the Dead 2: Contagium", + "film_vector": [ + -0.09722635895013809, + -0.32401278614997864, + 0.019761409610509872, + 0.12781347334384918, + 0.20687797665596008, + -0.23001626133918762, + 0.1363345980644226, + 0.08170980215072632, + 0.06859075278043747, + 0.014726413413882256 + ] + }, + { + "id": "/en/day_watch", + "initial_release_date": "2006-01-01", + "genre": [ + "Thriller", + "Fantasy", + "Action Film" + ], + "directed_by": [ + "Timur Bekmambetov" + ], + "name": "Day Watch", + "film_vector": [ + -0.44896137714385986, + -0.20666706562042236, + -0.16072121262550354, + 0.22516857087612152, + 0.24668815732002258, + -0.033684566617012024, + -0.03348778188228607, + -0.1572381556034088, + 0.02710474096238613, + -0.15080538392066956 + ] + }, + { + "id": "/en/day_zero", + "initial_release_date": "2007-11-02", + "genre": [ + "Indie film", + "Political drama", + "Drama" + ], + "directed_by": [ + "Bryan Gunnar Cole" + ], + "name": "Day Zero", + "film_vector": [ + -0.20326966047286987, + -0.02240600250661373, + -0.24897336959838867, + -0.15262135863304138, + 0.07285675406455994, + -0.21350906789302826, + -0.1418515145778656, + -0.13386550545692444, + 0.20268356800079346, + -0.04663824662566185 + ] + }, + { + "id": "/en/de-lovely", + "initial_release_date": "2004-05-22", + "genre": [ + "Musical", + "Biographical film", + "Musical Drama", + "Drama" + ], + "directed_by": [ + "Irwin Winkler" + ], + "name": "De-Lovely", + "film_vector": [ + -0.26329952478408813, + 0.17824463546276093, + -0.3471869230270386, + -0.11439169198274612, + 0.08073922991752625, + -0.1587848663330078, + -0.07611110806465149, + 0.2583734691143036, + 0.13700878620147705, + -0.15864138305187225 + ] + }, + { + "id": "/en/dead_breakfast", + "initial_release_date": "2004-03-19", + "genre": [ + "Horror", + "Black comedy", + "Creature Film", + "Zombie Film", + "Horror comedy", + "Comedy" + ], + "directed_by": [ + "Matthew Leutwyler" + ], + "name": "Dead & Breakfast", + "film_vector": [ + -0.3034135699272156, + -0.2166818380355835, + -0.3878512680530548, + 0.1761581003665924, + -0.16928982734680176, + -0.24109607934951782, + 0.30643230676651, + 0.14563412964344025, + 0.13067562878131866, + -0.09946100413799286 + ] + }, + { + "id": "/en/dead_birds_2005", + "initial_release_date": "2005-03-15", + "genre": [ + "Horror" + ], + "directed_by": [ + "Alex Turner" + ], + "name": "Dead Birds", + "film_vector": [ + 0.030362995341420174, + -0.2718079090118408, + 0.03855740278959274, + 0.03787025809288025, + 0.12360574305057526, + -0.0023325947113335133, + 0.21181747317314148, + 0.19097502529621124, + 0.11264768242835999, + 0.020237687975168228 + ] + }, + { + "id": "/en/dead_end_2003", + "initial_release_date": "2003-01-30", + "genre": [ + "Horror", + "Thriller", + "Mystery", + "Comedy" + ], + "directed_by": [ + "Jean-Baptiste Andrea", + "Fabrice Canepa" + ], + "name": "Dead End", + "film_vector": [ + -0.44875437021255493, + -0.3417016863822937, + -0.3574424386024475, + 0.035238202661275864, + -0.06820030510425568, + -0.03777723014354706, + 0.16677075624465942, + -0.08212724328041077, + 0.13330106437206268, + -0.08870524168014526 + ] + }, + { + "id": "/en/dead_friend", + "initial_release_date": "2004-06-18", + "genre": [ + "Horror", + "East Asian cinema", + "World cinema" + ], + "directed_by": [ + "Kim Tae-kyeong" + ], + "name": "Dead Friend", + "film_vector": [ + -0.36197972297668457, + -0.029662875458598137, + -0.017389632761478424, + 0.07426329702138901, + 0.04841833934187889, + -0.16675132513046265, + 0.25778812170028687, + 0.02102135680615902, + 0.2862839996814728, + -0.2549176514148712 + ] + }, + { + "id": "/en/dead_mans_shoes", + "initial_release_date": "2004-10-01", + "genre": [ + "Psychological thriller", + "Crime Fiction", + "Thriller", + "Drama" + ], + "directed_by": [ + "Shane Meadows" + ], + "name": "Dead Man's Shoes", + "film_vector": [ + -0.370442271232605, + -0.36290520429611206, + -0.2743346095085144, + -0.10983501374721527, + 0.05007345229387283, + -0.12566682696342468, + 0.11746963113546371, + 0.018126271665096283, + 0.01934911124408245, + -0.14459732174873352 + ] + }, + { + "id": "/en/dear_frankie", + "initial_release_date": "2004-05-04", + "genre": [ + "Indie film", + "Drama", + "Romance Film" + ], + "directed_by": [ + "Shona Auerbach" + ], + "name": "Dear Frankie", + "film_vector": [ + -0.22327058017253876, + 0.004663696512579918, + -0.4014565050601959, + 0.021681873127818108, + 0.3390662670135498, + -0.17027926445007324, + -0.1288691759109497, + -0.11639110743999481, + 0.22385531663894653, + -0.1599562019109726 + ] + }, + { + "id": "/en/dear_wendy", + "initial_release_date": "2004-05-16", + "genre": [ + "Indie film", + "Crime Fiction", + "Melodrama", + "Comedy", + "Romance Film", + "Drama" + ], + "directed_by": [ + "Thomas Vinterberg" + ], + "name": "Dear Wendy", + "film_vector": [ + -0.39021068811416626, + -0.05393758416175842, + -0.4615771770477295, + 0.09167865663766861, + 0.1268254816532135, + -0.1147637888789177, + -0.043434031307697296, + -0.06029018014669418, + 0.15360240638256073, + -0.24171003699302673 + ] + }, + { + "id": "/en/death_in_gaza", + "initial_release_date": "2004-02-11", + "genre": [ + "Documentary film", + "War film", + "Children's Issues", + "Culture & Society", + "Biographical film" + ], + "directed_by": [ + "James Miller" + ], + "name": "Death in Gaza", + "film_vector": [ + -0.16105593740940094, + 0.04105151444673538, + 0.041253071278333664, + -0.1649584174156189, + -0.07176008075475693, + -0.31978678703308105, + -0.16430246829986572, + 0.023427991196513176, + 0.2410966455936432, + -0.07107236236333847 + ] + }, + { + "id": "/en/death_to_smoochy", + "initial_release_date": "2002-03-29", + "genre": [ + "Comedy", + "Thriller", + "Crime Fiction", + "Drama" + ], + "directed_by": [ + "Danny DeVito" + ], + "name": "Death to Smoochy", + "film_vector": [ + -0.4131348729133606, + -0.09359930455684662, + -0.2896167039871216, + -0.1059049740433693, + -0.17333225905895233, + 0.014631465077400208, + 0.18149977922439575, + -0.07450158149003983, + 0.08677924424409866, + -0.1627989113330841 + ] + }, + { + "id": "/en/death_trance", + "initial_release_date": "2005-05-12", + "genre": [ + "Action Film", + "Fantasy", + "Martial Arts Film", + "Thriller", + "Action/Adventure", + "World cinema", + "Action Thriller", + "Japanese Movies" + ], + "directed_by": [ + "Yuji Shimomura" + ], + "name": "Death Trance", + "film_vector": [ + -0.6245324611663818, + -0.11933362483978271, + -0.03202090039849281, + 0.1831030398607254, + -0.03380788490176201, + -0.17994481325149536, + 0.043341606855392456, + 0.0785493403673172, + 0.09186800569295883, + -0.015435390174388885 + ] + }, + { + "id": "/en/death_walks_the_streets", + "initial_release_date": "2008-06-26", + "genre": [ + "Indie film", + "Horror", + "Crime Fiction" + ], + "directed_by": [ + "James Zahn" + ], + "name": "Death Walks the Streets", + "film_vector": [ + -0.3333437740802765, + -0.34843167662620544, + -0.11890411376953125, + -0.04578917846083641, + 0.12981876730918884, + -0.23517633974552155, + 0.1240132600069046, + -0.07940442860126495, + 0.21373426914215088, + -0.17780545353889465 + ] + }, + { + "id": "/en/deathwatch", + "initial_release_date": "2002-10-06", + "genre": [ + "Horror", + "War film", + "Thriller", + "Drama" + ], + "directed_by": [ + "Michael J. Bassett" + ], + "name": "Deathwatch", + "film_vector": [ + -0.48667043447494507, + -0.20607641339302063, + -0.06801754236221313, + 0.005850810557603836, + 0.003391016274690628, + -0.17305636405944824, + -0.01043515745550394, + -0.04804261773824692, + 0.05322461575269699, + -0.034492865204811096 + ] + }, + { + "id": "/en/december_boys", + "genre": [ + "Coming of age", + "Film adaptation", + "Indie film", + "Historical period drama", + "World cinema", + "Drama" + ], + "directed_by": [ + "Rod Hardy" + ], + "name": "December Boys", + "film_vector": [ + -0.24553392827510834, + 0.09771985560655594, + -0.1594979465007782, + 0.027297066524624825, + 0.032824646681547165, + -0.14432293176651, + -0.10790005326271057, + -0.014829009771347046, + 0.2610410451889038, + -0.20364373922348022 + ] + }, + { + "id": "/en/decoys", + "genre": [ + "Science Fiction", + "Horror", + "Thriller", + "Alien Film", + "Horror comedy" + ], + "directed_by": [ + "Matthew Hastings" + ], + "name": "Decoys", + "film_vector": [ + -0.41498643159866333, + -0.36756864190101624, + -0.1390339881181717, + 0.056753940880298615, + 0.025806209072470665, + -0.08060185611248016, + 0.25274622440338135, + 0.027403980493545532, + 0.1144566759467125, + -0.08951480686664581 + ] + }, + { + "id": "/en/deepavali", + "initial_release_date": "2007-02-09", + "genre": [ + "Romance Film", + "Tamil cinema", + "World cinema" + ], + "directed_by": [ + "Ezhil" + ], + "name": "Deepavali", + "film_vector": [ + -0.5300292372703552, + 0.3999411463737488, + -0.05398797616362572, + 0.0431164912879467, + 0.2147851586341858, + -0.08879183232784271, + 0.09998402744531631, + -0.04541696235537529, + 0.015315337106585503, + -0.10251809656620026 + ] + }, + { + "id": "/en/deewane_huye_pagal", + "initial_release_date": "2005-11-25", + "genre": [ + "Romance Film", + "Romantic comedy", + "Comedy", + "Bollywood", + "World cinema", + "Drama" + ], + "directed_by": [ + "Vikram Bhatt" + ], + "name": "Deewane Huye Paagal", + "film_vector": [ + -0.458416223526001, + 0.395083487033844, + -0.24820512533187866, + 0.07365268468856812, + 0.21701303124427795, + -0.06852594017982483, + 0.09818945825099945, + -0.004696917720139027, + -0.04045874997973442, + -0.05261623114347458 + ] + }, + { + "id": "/wikipedia/ja_id/980449", + "initial_release_date": "2006-11-20", + "genre": [ + "Thriller", + "Science Fiction", + "Time travel", + "Action Film", + "Mystery", + "Crime Thriller", + "Action/Adventure" + ], + "directed_by": [ + "Tony Scott" + ], + "name": "D\u00e9j\u00e0 Vu", + "film_vector": [ + -0.5238475203514099, + -0.29676684737205505, + -0.22253727912902832, + 0.09354038536548615, + 0.04029522463679314, + -0.0856875479221344, + -0.04720737412571907, + -0.05951875448226929, + 0.0025924863293766975, + -0.05292634293437004 + ] + }, + { + "id": "/en/democrazy_2005", + "genre": [ + "Parody", + "Action/Adventure", + "Action Film", + "Indie film", + "Superhero movie", + "Comedy" + ], + "directed_by": [ + "Michael Legge" + ], + "name": "Democrazy", + "film_vector": [ + -0.22354327142238617, + -0.11078530550003052, + -0.3020603060722351, + 0.20084302127361298, + -0.1323028951883316, + -0.24964705109596252, + 0.033001989126205444, + -0.1025153324007988, + -0.012581845745444298, + -0.0464211106300354 + ] + }, + { + "id": "/en/demonium", + "initial_release_date": "2001-08-25", + "genre": [ + "Horror", + "Thriller" + ], + "directed_by": [ + "Andreas Schnaas" + ], + "name": "Demonium", + "film_vector": [ + -0.3418945074081421, + -0.36501967906951904, + -0.015600967220962048, + -0.016947900876402855, + 0.23056268692016602, + -0.03888623043894768, + 0.1702871322631836, + 0.06458590924739838, + 0.08957711607217789, + -0.14284749329090118 + ] + }, + { + "id": "/en/der_schuh_des_manitu", + "initial_release_date": "2001-07-13", + "genre": [ + "Western", + "Comedy", + "Parody" + ], + "directed_by": [ + "Michael Herbig" + ], + "name": "Der Schuh des Manitu", + "film_vector": [ + -0.0027847308665513992, + 0.1785273253917694, + -0.09499980509281158, + -0.04367036372423172, + -0.0014007221907377243, + -0.2777767479419708, + 0.2714877426624298, + 0.09984353929758072, + -0.058543093502521515, + -0.2666703164577484 + ] + }, + { + "id": "/en/der_tunnel", + "initial_release_date": "2001-01-21", + "genre": [ + "World cinema", + "Thriller", + "Political drama", + "Political thriller", + "Drama" + ], + "directed_by": [ + "Roland Suso Richter" + ], + "name": "The Tunnel", + "film_vector": [ + -0.3576214909553528, + -0.11014334112405777, + -0.05855884402990341, + -0.17227935791015625, + 0.020168736577033997, + -0.1706576645374298, + -0.033890511840581894, + 0.10231921076774597, + 0.0788770467042923, + -0.1010463535785675 + ] + }, + { + "id": "/en/derailed", + "initial_release_date": "2005-11-11", + "genre": [ + "Thriller", + "Psychological thriller", + "Crime Thriller", + "Drama" + ], + "directed_by": [ + "Mikael H\u00e5fstr\u00f6m" + ], + "name": "Derailed", + "film_vector": [ + -0.513961911201477, + -0.2886124849319458, + -0.35072940587997437, + -0.13134267926216125, + -0.005919216200709343, + -0.03088376671075821, + 0.0017005072440952063, + 0.025902066379785538, + 0.000918031670153141, + 0.051335424184799194 + ] + }, + { + "id": "/en/derailed_2002", + "genre": [ + "Thriller", + "Action Film", + "Martial Arts Film", + "Disaster Film", + "Action/Adventure" + ], + "directed_by": [ + "Bob Misiorowski" + ], + "name": "Derailed", + "film_vector": [ + -0.4862247705459595, + -0.20438887178897858, + -0.23389384150505066, + 0.17084234952926636, + 0.10241171717643738, + -0.20481356978416443, + -0.10721373558044434, + -0.11471192538738251, + -0.05586468055844307, + 0.08028838038444519 + ] + }, + { + "id": "/en/destinys_child_live_in_atlana", + "initial_release_date": "2006-03-27", + "genre": [ + "Music", + "Documentary film" + ], + "directed_by": [ + "Julia Knowles" + ], + "name": "Destiny's Child: Live In Atlana", + "film_vector": [ + 0.020717794075608253, + 0.038227833807468414, + -0.0929197147488594, + -0.0754656195640564, + 0.07933254539966583, + -0.2207542061805725, + -0.21424397826194763, + -0.01179659366607666, + 0.37075501680374146, + 0.096292644739151 + ] + }, + { + "id": "/en/deuce_bigalow_european_gigolo", + "initial_release_date": "2005-08-06", + "name": "Deuce Bigalow: European Gigolo", + "directed_by": [ + "Mike Bigelow" + ], + "genre": [ + "Sex comedy", + "Slapstick", + "Gross out", + "Gross-out film", + "Comedy" + ], + "film_vector": [ + -0.00283006951212883, + -0.05554073303937912, + -0.2945348918437958, + 0.06112653762102127, + 0.06194871664047241, + -0.31801822781562805, + 0.2181098759174347, + -0.006265386939048767, + -0.09024812281131744, + -0.2383175492286682 + ] + }, + { + "id": "/en/dev", + "initial_release_date": "2004-06-11", + "name": "Dev", + "directed_by": [ + "Govind Nihalani" + ], + "genre": [ + "Drama", + "Bollywood" + ], + "film_vector": [ + -0.314998060464859, + 0.25877922773361206, + -0.027655240148305893, + -0.1994180679321289, + 0.03579064831137657, + 0.05028875172138214, + 0.13488225638866425, + -0.13306695222854614, + -0.05945481359958649, + 0.0787409096956253 + ] + }, + { + "id": "/en/devadasu", + "initial_release_date": "2006-01-11", + "name": "Devadasu", + "directed_by": [ + "YVS Chowdary", + "Gopireddy Mallikarjuna Reddy" + ], + "genre": [ + "Romance Film", + "Drama", + "Tollywood", + "World cinema" + ], + "film_vector": [ + -0.5723658800125122, + 0.349712997674942, + -0.027595307677984238, + 0.03816123679280281, + 0.12077102065086365, + -0.05743193253874779, + 0.10721540451049805, + -0.08469517529010773, + 0.07360599935054779, + -0.048418764024972916 + ] + }, + { + "id": "/en/devdas_2002", + "initial_release_date": "2002-05-23", + "name": "Devdas", + "directed_by": [ + "Sanjay Leela Bhansali" + ], + "genre": [ + "Romance Film", + "Musical", + "Drama", + "Bollywood", + "World cinema", + "Musical Drama" + ], + "film_vector": [ + -0.4970088005065918, + 0.33909547328948975, + -0.14074493944644928, + -0.03977203741669655, + 0.04293781518936157, + -0.037550926208496094, + 0.052294518798589706, + 0.05576945096254349, + -0.017665037885308266, + 0.05487441271543503 + ] + }, + { + "id": "/en/devils_playground_2003", + "initial_release_date": "2003-02-04", + "name": "Devil's Playground", + "directed_by": [ + "Lucy Walker" + ], + "genre": [ + "Documentary film" + ], + "film_vector": [ + 0.05251220986247063, + -0.24554681777954102, + 0.10043644905090332, + -0.03191428259015083, + 0.09947802126407623, + -0.24226054549217224, + 0.025467602536082268, + 0.060132693499326706, + 0.17305901646614075, + 0.009733575396239758 + ] + }, + { + "id": "/en/the_devils_pond", + "initial_release_date": "2003-10-21", + "name": "Devil's Pond", + "directed_by": [ + "Joel Viertel" + ], + "genre": [ + "Thriller", + "Suspense" + ], + "film_vector": [ + -0.16789096593856812, + -0.3775367736816406, + -0.055701062083244324, + -0.04114807769656181, + 0.26453879475593567, + 0.03350694477558136, + 0.08983799815177917, + 0.05562067776918411, + 0.020959459245204926, + -0.12337180972099304 + ] + }, + { + "id": "/en/dhadkan", + "initial_release_date": "2000-08-11", + "name": "Dhadkan", + "directed_by": [ + "Dharmesh Darshan" + ], + "genre": [ + "Musical", + "Romance Film", + "Melodrama", + "Bollywood", + "World cinema", + "Drama", + "Musical Drama" + ], + "film_vector": [ + -0.595303475856781, + 0.37460461258888245, + -0.21720202267169952, + 0.01841653324663639, + -0.0005767792463302612, + -0.1082804799079895, + 0.027217291295528412, + 0.09012522548437119, + -0.016618555411696434, + 0.028789948672056198 + ] + }, + { + "id": "/en/dhool", + "initial_release_date": "2003-01-10", + "name": "Dhool", + "directed_by": [ + "Dharani" + ], + "genre": [ + "Musical", + "Family", + "Action Film", + "Tamil cinema", + "World cinema", + "Drama", + "Musical Drama" + ], + "film_vector": [ + -0.5693018436431885, + 0.4070513844490051, + -0.11099158227443695, + 0.0429673045873642, + -0.03166954219341278, + -0.09538441896438599, + 0.043457262217998505, + 0.0506933368742466, + -0.0024888934567570686, + 0.02305549383163452 + ] + }, + { + "id": "/en/dhoom_2", + "initial_release_date": "2006-11-23", + "name": "Dhoom 2", + "directed_by": [ + "Sanjay Gadhvi" + ], + "genre": [ + "Crime Fiction", + "Action/Adventure", + "Musical", + "World cinema", + "Buddy cop film", + "Action Film", + "Thriller", + "Action Thriller", + "Musical comedy", + "Comedy" + ], + "film_vector": [ + -0.619939386844635, + 0.09894897788763046, + -0.2927732467651367, + 0.10728249698877335, + -0.07302822172641754, + -0.10894457995891571, + 0.10209449380636215, + -0.040146082639694214, + -0.20374739170074463, + 0.08068854361772537 + ] + }, + { + "id": "/en/dhyaas_parva", + "name": "Dhyaas Parva", + "directed_by": [ + "Amol Palekar" + ], + "genre": [ + "Biographical film", + "Drama", + "Marathi cinema" + ], + "film_vector": [ + -0.38600262999534607, + 0.3099507689476013, + -0.0001333393156528473, + -0.026858359575271606, + 0.13719338178634644, + -0.15993306040763855, + 0.1419367790222168, + -0.02168208360671997, + -0.04368189349770546, + -0.07842069864273071 + ] + }, + { + "id": "/en/diary_of_a_housewife", + "name": "Diary of a Housewife", + "directed_by": [ + "Vinod Sukumaran" + ], + "genre": [ + "Short Film", + "Malayalam Cinema", + "World cinema" + ], + "film_vector": [ + -0.3103427290916443, + 0.3299145996570587, + -0.04226815328001976, + 0.01167583279311657, + 0.15472312271595, + -0.1783810406923294, + 0.18065908551216125, + -0.08450464904308319, + 0.11471062153577805, + -0.1298006772994995 + ] + }, + { + "id": "/en/diary_of_a_mad_black_woman", + "initial_release_date": "2005-02-25", + "name": "Diary of a Mad Black Woman", + "directed_by": [ + "Darren Grant" + ], + "genre": [ + "Comedy-drama", + "Romance Film", + "Romantic comedy", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.12272959202528, + -0.00664939358830452, + -0.3802536725997925, + -0.11572908610105515, + 0.211839497089386, + -0.2505912482738495, + -0.027613436803221703, + 0.025454256683588028, + -0.015197400003671646, + -0.22047778964042664 + ] + }, + { + "id": "/en/dickie_roberts_former_child_star", + "initial_release_date": "2003-09-03", + "name": "Dickie Roberts: Former Child Star", + "directed_by": [ + "Sam Weisman" + ], + "genre": [ + "Parody", + "Slapstick", + "Comedy" + ], + "film_vector": [ + 0.2450050562620163, + 0.08927500247955322, + -0.22769373655319214, + 0.11361678689718246, + -0.19230380654335022, + -0.14823932945728302, + 0.22124022245407104, + -0.07130126655101776, + -0.01567109115421772, + -0.23691052198410034 + ] + }, + { + "id": "/en/die_bad", + "initial_release_date": "2000-07-15", + "name": "Die Bad", + "directed_by": [ + "Ryoo Seung-wan" + ], + "genre": [ + "Crime Fiction", + "Drama" + ], + "film_vector": [ + -0.36344480514526367, + -0.2506151497364044, + -0.07736779004335403, + -0.26877209544181824, + -0.03591574728488922, + 0.021924447268247604, + 0.10233789682388306, + -0.11354915052652359, + 0.010611845180392265, + -0.2690621614456177 + ] + }, + { + "id": "/en/die_mommie_die", + "initial_release_date": "2003-01-20", + "name": "Die Mommie Die!", + "directed_by": [ + "Mark Rucker" + ], + "genre": [ + "Comedy" + ], + "film_vector": [ + 0.11833133548498154, + -0.05143843963742256, + -0.32677164673805237, + 0.12381883710622787, + 0.023979801684617996, + -0.12686321139335632, + 0.275659441947937, + -0.08758075535297394, + 0.01702159084379673, + -0.024749819189310074 + ] + }, + { + "id": "/en/dieu_est_grand_je_suis_toute_petite", + "initial_release_date": "2001-09-26", + "name": "God Is Great and I'm Not", + "directed_by": [ + "Pascale Bailly" + ], + "genre": [ + "Romantic comedy", + "World cinema", + "Religious Film", + "Romance Film", + "Comedy of manners", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.41392844915390015, + 0.28678375482559204, + -0.46296048164367676, + 0.06454585492610931, + 0.0015490383375436068, + -0.11264899373054504, + 0.05580790340900421, + 0.06779341399669647, + 0.0036294162273406982, + -0.12243588268756866 + ] + }, + { + "id": "/en/digimon_the_movie", + "initial_release_date": "2000-03-17", + "name": "Digimon: The Movie", + "directed_by": [ + "Mamoru Hosoda", + "Shigeyasu Yamauchi" + ], + "genre": [ + "Anime", + "Fantasy", + "Family", + "Animation", + "Adventure Film", + "Action Film", + "Thriller" + ], + "film_vector": [ + -0.29677721858024597, + -0.041870806366205215, + 0.06827671080827713, + 0.4105851650238037, + 0.007415592670440674, + 0.0320107601583004, + 0.01423653680831194, + -0.02770104631781578, + 0.012563923373818398, + -0.06575045734643936 + ] + }, + { + "id": "/en/digital_monster_x-evolution", + "initial_release_date": "2005-01-03", + "name": "Digital Monster X-Evolution", + "directed_by": [ + "Hiroyuki Kakud\u014d" + ], + "genre": [ + "Computer Animation", + "Animation", + "Japanese Movies" + ], + "film_vector": [ + -0.17710083723068237, + -0.03952481970191002, + 0.26974937319755554, + 0.4726451635360718, + -0.06535698473453522, + 0.0476425439119339, + 0.09255917370319366, + 0.09114424139261246, + 0.11632723361253738, + 0.013457970693707466 + ] + }, + { + "id": "/en/digna_hasta_el_ultimo_aliento", + "initial_release_date": "2004-12-17", + "name": "Digna... hasta el \u00faltimo aliento", + "directed_by": [ + "Felipe Cazals" + ], + "genre": [ + "Documentary film", + "Culture & Society", + "Law & Crime", + "Biographical film" + ], + "film_vector": [ + -0.1785144805908203, + -0.024796118959784508, + 0.010609762743115425, + -0.06793801486492157, + 0.05668042227625847, + -0.3080732226371765, + -0.017276063561439514, + -0.015596484765410423, + 0.14117617905139923, + -0.08589357137680054 + ] + }, + { + "id": "/en/dil_chahta_hai", + "initial_release_date": "2001-07-24", + "name": "Dil Chahta Hai", + "directed_by": [ + "Farhan Akhtar" + ], + "genre": [ + "Bollywood", + "Musical", + "Romance Film", + "World cinema", + "Comedy-drama", + "Musical Drama", + "Musical comedy", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.478620320558548, + 0.38018175959587097, + -0.31591588258743286, + -0.03829556331038475, + -0.021836116909980774, + -0.1419517695903778, + 0.1314362734556198, + 0.1159333884716034, + -0.08600441366434097, + 0.10057583451271057 + ] + }, + { + "id": "/en/dil_diya_hai", + "initial_release_date": "2006-09-08", + "name": "Dil Diya Hai", + "directed_by": [ + "Aditya Datt", + "Aditya Datt" + ], + "genre": [ + "Romance Film", + "Bollywood", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.5669327974319458, + 0.42651402950286865, + -0.18563690781593323, + -0.005403580144047737, + 0.09328802675008774, + -0.06847497820854187, + 0.1109740138053894, + -0.07530290633440018, + 0.04181893542408943, + 0.017834538593888283 + ] + }, + { + "id": "/en/dil_hai_tumhaara", + "initial_release_date": "2002-09-06", + "name": "Dil Hai Tumhara", + "directed_by": [ + "Kundan Shah" + ], + "genre": [ + "Family", + "Romance Film", + "Musical", + "Bollywood", + "World cinema", + "Drama", + "Musical Drama" + ], + "film_vector": [ + -0.4750450551509857, + 0.43507665395736694, + -0.19241474568843842, + -0.00434509664773941, + 0.010258086025714874, + -0.05984663963317871, + 0.08588433265686035, + 0.03373494744300842, + -0.023599926382303238, + 0.04929716885089874 + ] + }, + { + "id": "/en/dil_ka_rishta", + "initial_release_date": "2003-01-17", + "name": "Dil Ka Rishta", + "directed_by": [ + "Naresh Malhotra" + ], + "genre": [ + "Romance Film", + "Bollywood" + ], + "film_vector": [ + -0.276568740606308, + 0.26562631130218506, + -0.16647014021873474, + 0.05111797899007797, + 0.45435571670532227, + -0.06749340891838074, + 0.1217002421617508, + -0.10932319611310959, + -0.0286356620490551, + 0.012603091076016426 + ] + }, + { + "id": "/en/dil_ne_jise_apna_kahaa", + "initial_release_date": "2004-09-10", + "name": "Dil Ne Jise Apna Kahaa", + "directed_by": [ + "Atul Agnihotri" + ], + "genre": [ + "Musical", + "World cinema", + "Romance Film", + "Musical Drama", + "Musical comedy", + "Comedy", + "Bollywood", + "Drama" + ], + "film_vector": [ + -0.4943229556083679, + 0.4185795783996582, + -0.3291330337524414, + -0.01011788658797741, + -0.05923565849661827, + -0.12412341684103012, + 0.10625706613063812, + 0.08043383061885834, + -0.00032909191213548183, + 0.07313648611307144 + ] + }, + { + "id": "/en/dinosaur_2000", + "initial_release_date": "2000-05-13", + "name": "Dinosaur", + "directed_by": [ + "Eric Leighton", + "Ralph Zondag" + ], + "genre": [ + "Computer Animation", + "Animation", + "Fantasy", + "Costume drama", + "Family", + "Adventure Film", + "Thriller" + ], + "film_vector": [ + -0.4176998734474182, + -0.016637761145830154, + 0.00347018800675869, + 0.47585201263427734, + -0.28846320509910583, + 0.07842106372117996, + -0.08420534431934357, + -0.008168362081050873, + 0.1440243273973465, + -0.06413199752569199 + ] + }, + { + "id": "/en/dirty_dancing_2004", + "initial_release_date": "2004-02-27", + "name": "Dirty Dancing: Havana Nights", + "directed_by": [ + "Guy Ferland" + ], + "genre": [ + "Musical", + "Coming of age", + "Indie film", + "Teen film", + "Romance Film", + "Historical period drama", + "Dance film", + "Musical Drama", + "Drama" + ], + "film_vector": [ + -0.42458486557006836, + 0.05896534025669098, + -0.4280267357826233, + -0.0016242703422904015, + -0.08712584525346756, + -0.26909491419792175, + -0.1722278594970703, + 0.04870247840881348, + 0.09686781466007233, + -0.011229136027395725 + ] + }, + { + "id": "/en/dirty_deeds", + "initial_release_date": "2002-07-18", + "name": "Dirty Deeds", + "directed_by": [ + "David Caesar" + ], + "genre": [ + "Historical period drama", + "Black comedy", + "Crime Thriller", + "Thriller", + "Crime Fiction", + "World cinema", + "Gangster Film", + "Drama" + ], + "film_vector": [ + -0.5251175165176392, + -0.09964907169342041, + -0.25482431054115295, + -0.18620994687080383, + -0.07618263363838196, + -0.20498475432395935, + 0.06479014456272125, + 0.025306040421128273, + -0.10351210832595825, + -0.17840026319026947 + ] + }, + { + "id": "/en/dirty_deeds_2005", + "initial_release_date": "2005-08-26", + "name": "Dirty Deeds", + "directed_by": [ + "David Kendall" + ], + "genre": [ + "Comedy" + ], + "film_vector": [ + 0.0424397736787796, + -0.06560762971639633, + -0.2677696943283081, + 0.0030851121991872787, + 0.1025625616312027, + -0.20182287693023682, + 0.22306224703788757, + -0.1062820702791214, + -0.060400351881980896, + -0.1738733947277069 + ] + }, + { + "id": "/en/dirty_love", + "initial_release_date": "2005-09-23", + "name": "Dirty Love", + "directed_by": [ + "John Mallory Asher" + ], + "genre": [ + "Indie film", + "Sex comedy", + "Romantic comedy", + "Romance Film", + "Comedy" + ], + "film_vector": [ + -0.3477535843849182, + 0.042552024126052856, + -0.6052619814872742, + 0.0845087319612503, + 0.1328701376914978, + -0.22924286127090454, + 0.03243926167488098, + 0.050743330270051956, + 0.05258830636739731, + -0.019502125680446625 + ] + }, + { + "id": "/en/disappearing_acts", + "initial_release_date": "2000-12-09", + "name": "Disappearing Acts", + "directed_by": [ + "Gina Prince-Bythewood" + ], + "genre": [ + "Romance Film", + "Television film", + "Film adaptation", + "Comedy-drama", + "Drama" + ], + "film_vector": [ + -0.3599739074707031, + 0.0553218238055706, + -0.3734056055545807, + -0.08374472707509995, + 0.030182570219039917, + -0.15710386633872986, + 0.00525722187012434, + -0.04219038784503937, + 0.09224580973386765, + -0.13712048530578613 + ] + }, + { + "id": "/en/dishyum", + "initial_release_date": "2006-02-02", + "name": "Dishyum", + "directed_by": [ + "Sasi" + ], + "genre": [ + "Romance Film", + "Action Film", + "Drama", + "Tamil cinema", + "World cinema" + ], + "film_vector": [ + -0.6248939037322998, + 0.38985922932624817, + -0.08500711619853973, + 0.0684470534324646, + 0.03843052685260773, + -0.11477720737457275, + 0.05153300613164902, + -0.08628179877996445, + -0.01859808713197708, + -0.024098489433526993 + ] + }, + { + "id": "/en/distant_lights", + "initial_release_date": "2003-02-11", + "name": "Distant Lights", + "directed_by": [ + "Hans-Christian Schmid" + ], + "genre": [ + "Drama" + ], + "film_vector": [ + 0.025784999132156372, + -0.01462782546877861, + 0.008019955828785896, + -0.19034989178180695, + 0.056675903499126434, + 0.1350032240152359, + -0.061414606869220734, + 0.1523847132921219, + 0.02491295151412487, + 0.009053094312548637 + ] + }, + { + "id": "/en/district_b13", + "initial_release_date": "2004-11-10", + "name": "District 13", + "directed_by": [ + "Pierre Morel" + ], + "genre": [ + "Martial Arts Film", + "Thriller", + "Action Film", + "Science Fiction", + "Crime Fiction" + ], + "film_vector": [ + -0.4381856322288513, + -0.21516825258731842, + -0.13509228825569153, + 0.06480198353528976, + 0.010355194099247456, + -0.15488693118095398, + -0.07503782212734222, + -0.14776980876922607, + -0.03355038911104202, + 0.008360558189451694 + ] + }, + { + "id": "/en/disturbia", + "initial_release_date": "2007-04-04", + "name": "Disturbia", + "directed_by": [ + "D. J. Caruso" + ], + "genre": [ + "Thriller", + "Mystery", + "Teen film", + "Drama" + ], + "film_vector": [ + -0.44158488512039185, + -0.26235342025756836, + -0.22472669184207916, + 0.04986193776130676, + 0.2159997522830963, + -0.046482667326927185, + -0.0074217962101101875, + -0.06790678203105927, + 0.2822877764701843, + -0.028353482484817505 + ] + }, + { + "id": "/en/ditto_2000", + "initial_release_date": "2000-05-27", + "name": "Ditto", + "directed_by": [ + "Jeong-kwon Kim" + ], + "genre": [ + "Romance Film", + "Science Fiction", + "East Asian cinema", + "World cinema" + ], + "film_vector": [ + -0.6195796728134155, + 0.2557748854160309, + -0.11997005343437195, + 0.10401451587677002, + -0.11417630314826965, + -0.07066985964775085, + -0.0018220647471025586, + -0.11538927257061005, + 0.20544810593128204, + -0.1657240390777588 + ] + }, + { + "id": "/en/divine_intervention_2002", + "initial_release_date": "2002-05-19", + "name": "Divine Intervention", + "directed_by": [ + "Elia Suleiman" + ], + "genre": [ + "Black comedy", + "World cinema", + "Romance Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.36446478962898254, + 0.1819705218076706, + -0.28437650203704834, + -0.1032136082649231, + -0.024786779657006264, + -0.12867236137390137, + 0.044094253331422806, + 0.008003205060958862, + 0.10949265956878662, + -0.22623354196548462 + ] + }, + { + "id": "/en/divine_secrets_of_the_ya_ya_sisterhood", + "initial_release_date": "2002-06-03", + "name": "Divine Secrets of the Ya-Ya Sisterhood", + "directed_by": [ + "Callie Khouri" + ], + "genre": [ + "Film adaptation", + "Comedy-drama", + "Historical period drama", + "Family Drama", + "Ensemble Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.14706331491470337, + 0.07223695516586304, + -0.3456464409828186, + 0.03060143068432808, + 0.13784784078598022, + -0.10467110574245453, + -0.11972437798976898, + 0.17114892601966858, + 0.00939476490020752, + -0.2667278051376343 + ] + }, + { + "id": "/en/doa_dead_or_alive", + "initial_release_date": "2006-09-07", + "name": "DOA: Dead or Alive", + "directed_by": [ + "Corey Yuen" + ], + "genre": [ + "Action Film", + "Adventure Film" + ], + "film_vector": [ + -0.2187821865081787, + -0.11624310910701752, + 0.08415783196687698, + 0.23974651098251343, + 0.11407551914453506, + -0.20337006449699402, + 0.007771981880068779, + -0.11541461944580078, + -0.04634963348507881, + -0.1036582887172699 + ] + }, + { + "id": "/en/dodgeball_a_true_underdog_story", + "initial_release_date": "2004-06-18", + "name": "DodgeBall: A True Underdog Story", + "directed_by": [ + "Rawson Marshall Thurber" + ], + "genre": [ + "Sports", + "Comedy" + ], + "film_vector": [ + 0.08017759025096893, + 0.01944085955619812, + -0.20649948716163635, + 0.049214743077754974, + -0.10984599590301514, + -0.20172902941703796, + -0.07814192026853561, + -0.2894688844680786, + -0.13334619998931885, + -0.046542517840862274 + ] + }, + { + "id": "/en/dog_soldiers", + "initial_release_date": "2002-03-22", + "name": "Dog Soldiers", + "directed_by": [ + "Neil Marshall" + ], + "genre": [ + "Horror", + "Action Film", + "Creature Film" + ], + "film_vector": [ + -0.26398777961730957, + -0.17131149768829346, + -0.014935456216335297, + 0.25702670216560364, + 0.06751534342765808, + -0.26633280515670776, + 0.007661312818527222, + -0.02809661626815796, + 0.01366239320486784, + -0.18957367539405823 + ] + }, + { + "id": "/en/dogtown_and_z-boys", + "initial_release_date": "2001-01-19", + "name": "Dogtown and Z-Boys", + "directed_by": [ + "Stacy Peralta" + ], + "genre": [ + "Documentary film", + "Sports", + "Extreme Sports", + "Biographical film" + ], + "film_vector": [ + 0.00940174050629139, + -0.07929427176713943, + -0.0531400702893734, + 0.08611267805099487, + -0.1355009377002716, + -0.3445637822151184, + -0.23339882493019104, + -0.18944582343101501, + 0.06151154637336731, + -0.0649382621049881 + ] + }, + { + "id": "/en/dogville", + "initial_release_date": "2003-05-19", + "name": "Dogville", + "directed_by": [ + "Lars von Trier" + ], + "genre": [ + "Drama" + ], + "film_vector": [ + 0.1885179877281189, + -0.09078849852085114, + -0.05343598127365112, + -0.1128959059715271, + 0.00040294229984283447, + 0.131043940782547, + -0.13147133588790894, + -0.03354529291391373, + 0.029193803668022156, + -0.04727563261985779 + ] + }, + { + "id": "/en/doll_master", + "initial_release_date": "2004-07-30", + "name": "The Doll Master", + "directed_by": [ + "Jeong Yong-Gi" + ], + "genre": [ + "Horror", + "Thriller", + "East Asian cinema", + "World cinema" + ], + "film_vector": [ + -0.4063144326210022, + 0.008646471425890923, + 0.010246850550174713, + 0.14175039529800415, + 0.10301771014928818, + -0.134393572807312, + 0.19645023345947266, + 0.06356023997068405, + 0.2992929220199585, + -0.25281643867492676 + ] + }, + { + "id": "/en/dolls", + "initial_release_date": "2002-09-05", + "name": "Dolls", + "directed_by": [ + "Takeshi Kitano" + ], + "genre": [ + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.14501291513442993, + 0.11532430350780487, + -0.27207350730895996, + 0.11480943113565445, + 0.4084615111351013, + 0.04680132493376732, + -0.05977592617273331, + -0.006389454938471317, + 0.2800059914588928, + -0.24549663066864014 + ] + }, + { + "id": "/en/dominion_prequel_to_the_exorcist", + "initial_release_date": "2005-05-20", + "name": "Dominion: Prequel to the Exorcist", + "directed_by": [ + "Paul Schrader" + ], + "genre": [ + "Horror", + "Supernatural", + "Psychological thriller", + "Cult film" + ], + "film_vector": [ + -0.22209936380386353, + -0.3653218746185303, + 0.006781972944736481, + 0.08855326473712921, + 0.22177773714065552, + -0.16563540697097778, + 0.035750612616539, + 0.11236962676048279, + 0.06710352748632431, + -0.15184739232063293 + ] + }, + { + "id": "/en/domino_2005", + "initial_release_date": "2005-09-25", + "name": "Domino", + "directed_by": [ + "Tony Scott" + ], + "genre": [ + "Thriller", + "Action Film", + "Biographical film", + "Crime Fiction", + "Comedy", + "Adventure Film", + "Drama" + ], + "film_vector": [ + -0.5034433603286743, + -0.1384686529636383, + -0.32842564582824707, + 0.1093897894024849, + 0.018808118999004364, + -0.2185591757297516, + -0.08086839318275452, + -0.11516845226287842, + 2.8165988624095917e-05, + -0.08705727010965347 + ] + }, + { + "id": "/en/don_2006", + "initial_release_date": "2006-10-20", + "name": "Don: The Chase Begins Again", + "directed_by": [ + "Farhan Akhtar" + ], + "genre": [ + "Crime Fiction", + "Thriller", + "Mystery", + "Action Film", + "Romance Film", + "Comedy", + "Bollywood", + "World cinema" + ], + "film_vector": [ + -0.5188473463058472, + 0.022436287254095078, + -0.13629776239395142, + 0.055435411632061005, + 0.041984010487794876, + -0.07025142759084702, + 0.04501733183860779, + -0.215736985206604, + -0.08836187422275543, + -0.12936051189899445 + ] + }, + { + "id": "/en/dons_plum", + "initial_release_date": "2001-02-10", + "name": "Don's Plum", + "directed_by": [ + "R.D. Robb" + ], + "genre": [ + "Black-and-white", + "Ensemble Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.05300581455230713, + 0.011945001780986786, + -0.39623451232910156, + 0.08701205253601074, + 0.06999285519123077, + -0.1830969750881195, + 0.06061392277479172, + -0.03072693757712841, + 0.07879045605659485, + -0.29746976494789124 + ] + }, + { + "id": "/en/dont_come_knocking", + "initial_release_date": "2005-05-19", + "name": "Don't Come Knocking", + "directed_by": [ + "Wim Wenders" + ], + "genre": [ + "Western", + "Indie film", + "Musical", + "Drama", + "Music", + "Musical Drama" + ], + "film_vector": [ + -0.31161874532699585, + 0.039457373321056366, + -0.3881570100784302, + 0.040919169783592224, + -0.095431387424469, + -0.2564992308616638, + -0.09866124391555786, + 0.0029436314944177866, + 0.09364783763885498, + -0.056875236332416534 + ] + }, + { + "id": "/en/dont_move", + "initial_release_date": "2004-03-12", + "name": "Don't Move", + "directed_by": [ + "Sergio Castellitto" + ], + "genre": [ + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.30267637968063354, + 0.1332448422908783, + -0.3222655653953552, + 0.007732677739113569, + 0.3650011718273163, + -0.02749072015285492, + -0.05808233469724655, + -0.0916474312543869, + 0.11306042224168777, + -0.12188668549060822 + ] + }, + { + "id": "/en/dont_say_a_word_2001", + "initial_release_date": "2001-09-24", + "name": "Don't Say a Word", + "directed_by": [ + "Gary Fleder" + ], + "genre": [ + "Thriller", + "Psychological thriller", + "Crime Fiction", + "Suspense" + ], + "film_vector": [ + -0.5842002630233765, + -0.39609628915786743, + -0.21068669855594635, + -0.1668110191822052, + -0.03778810799121857, + 0.03682178631424904, + 0.03515218570828438, + 0.10848072171211243, + -0.00839092954993248, + -0.09675154089927673 + ] + }, + { + "id": "/en/donnie_darko", + "initial_release_date": "2001-01-19", + "name": "Donnie Darko", + "directed_by": [ + "Richard Kelly" + ], + "genre": [ + "Science Fiction", + "Mystery", + "Drama" + ], + "film_vector": [ + -0.2780837416648865, + -0.2549389600753784, + -0.08734437823295593, + 0.019881559535861015, + -0.012743376195430756, + -0.028665076941251755, + -0.011864070780575275, + -0.10741620510816574, + 0.08361963927745819, + -0.21149450540542603 + ] + }, + { + "id": "/en/doomsday_2008", + "initial_release_date": "2008-03-14", + "name": "Doomsday", + "directed_by": [ + "Neil Marshall" + ], + "genre": [ + "Science Fiction", + "Action Film" + ], + "film_vector": [ + -0.1996731460094452, + -0.29149943590164185, + 0.05231541022658348, + 0.09793119132518768, + 0.20616856217384338, + -0.2712734341621399, + -0.042201653122901917, + -0.07979568094015121, + -0.14993596076965332, + 0.029493847861886024 + ] + }, + { + "id": "/en/dopamine_2003", + "initial_release_date": "2003-01-23", + "name": "Dopamine", + "directed_by": [ + "Mark Decena" + ], + "genre": [ + "Comedy-drama", + "Romance Film", + "Indie film", + "Romantic comedy", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.13995254039764404, + -0.029043840244412422, + -0.46299368143081665, + 0.07821152359247208, + 0.21441783010959625, + -0.19504719972610474, + 0.07376959919929504, + -0.0902048647403717, + 0.08438843488693237, + -0.10964285582304001 + ] + }, + { + "id": "/en/dosti_friends_forever", + "initial_release_date": "2005-12-23", + "name": "Dosti: Friends Forever", + "directed_by": [ + "Suneel Darshan" + ], + "genre": [ + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.19510391354560852, + 0.18766534328460693, + -0.19610200822353363, + 0.07101060450077057, + 0.40411901473999023, + -0.03450726717710495, + 0.06967533379793167, + -0.13560444116592407, + 0.09489107131958008, + -0.04496793448925018 + ] + }, + { + "id": "/en/double_take", + "initial_release_date": "2001-01-12", + "name": "Double Take", + "directed_by": [ + "George Gallo" + ], + "genre": [ + "Crime Fiction", + "Action/Adventure", + "Action Film", + "Comedy" + ], + "film_vector": [ + -0.40346595644950867, + -0.18837527930736542, + -0.24298809468746185, + 0.04323664307594299, + -0.07904528081417084, + -0.13745808601379395, + 0.017804166302084923, + -0.3025766611099243, + -0.10283053666353226, + -0.23782047629356384 + ] + }, + { + "id": "/en/double_teamed", + "initial_release_date": "2002-01-18", + "name": "Double Teamed", + "directed_by": [ + "Duwayne Dunham" + ], + "genre": [ + "Family", + "Biographical film", + "Family Drama", + "Children's/Family", + "Sports" + ], + "film_vector": [ + -0.18068094551563263, + 0.05919678509235382, + -0.3730890154838562, + 0.02629006654024124, + -0.24510154128074646, + 4.4230371713638306e-05, + -0.12198036909103394, + -0.2526334226131439, + 0.09253013134002686, + -0.13737495243549347 + ] + }, + { + "id": "/en/double_vision_2002", + "initial_release_date": "2002-05-20", + "name": "Double Vision", + "directed_by": [ + "Chen Kuo-Fu" + ], + "genre": [ + "Thriller", + "Mystery", + "Martial Arts Film", + "Action Film", + "Horror", + "Psychological thriller", + "Suspense", + "World cinema", + "Crime Thriller", + "Action/Adventure", + "Chinese Movies" + ], + "film_vector": [ + -0.656207799911499, + -0.11380210518836975, + -0.14597325026988983, + 0.12069053202867508, + 0.007611534558236599, + -0.14442962408065796, + 0.018941203132271767, + -0.0031632762402296066, + 0.058131903409957886, + -0.04490025341510773 + ] + }, + { + "id": "/en/double_whammy", + "initial_release_date": "2001-01-20", + "name": "Double Whammy", + "directed_by": [ + "Tom DiCillo" + ], + "genre": [ + "Comedy-drama", + "Indie film", + "Action Film", + "Crime Fiction", + "Action/Adventure", + "Satire", + "Romantic comedy", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.2688789665699005, + -0.09962473064661026, + -0.4565478563308716, + 0.05143091082572937, + 0.00822046771645546, + -0.2558712363243103, + 0.10267769545316696, + -0.054072603583335876, + -0.07664838433265686, + -0.1445460021495819 + ] + }, + { + "id": "/en/down_and_derby", + "initial_release_date": "2005-04-15", + "name": "Down and Derby", + "directed_by": [ + "Eric Hendershot" + ], + "genre": [ + "Family", + "Sports", + "Comedy" + ], + "film_vector": [ + 0.0448148250579834, + 0.13282349705696106, + -0.3120231032371521, + -0.02118515968322754, + -0.3072481155395508, + 0.059908680617809296, + 0.010155640542507172, + -0.10298594832420349, + 0.14852274954319, + -0.09472975134849548 + ] + }, + { + "id": "/en/down_in_the_valley", + "initial_release_date": "2005-05-13", + "name": "Down in the Valley", + "directed_by": [ + "David Jacobson" + ], + "genre": [ + "Indie film", + "Romance Film", + "Family Drama", + "Psychological thriller", + "Drama" + ], + "film_vector": [ + -0.468752920627594, + -0.1153697520494461, + -0.46190187335014343, + 0.04225721210241318, + -0.010483073070645332, + -0.1935444474220276, + -0.12291240692138672, + -0.11776615679264069, + 0.16643518209457397, + -0.020224448293447495 + ] + }, + { + "id": "/en/down_to_earth", + "initial_release_date": "2001-02-12", + "name": "Down to Earth", + "directed_by": [ + "Chris Weitz", + "Paul Weitz" + ], + "genre": [ + "Fantasy", + "Comedy" + ], + "film_vector": [ + -0.20068567991256714, + 0.02071724459528923, + -0.3209648132324219, + 0.23433947563171387, + -0.17529228329658508, + 0.15631103515625, + 0.03605201467871666, + -0.08211452513933182, + 0.1622825264930725, + -0.3506251573562622 + ] + }, + { + "id": "/en/down_with_love", + "initial_release_date": "2003-05-09", + "name": "Down with Love", + "directed_by": [ + "Peyton Reed" + ], + "genre": [ + "Romantic comedy", + "Romance Film", + "Screwball comedy", + "Parody", + "Comedy" + ], + "film_vector": [ + -0.1889198124408722, + 0.08793140947818756, + -0.6399146914482117, + 0.06009169667959213, + 0.02354561723768711, + -0.19972653687000275, + 0.020785439759492874, + 0.07970035076141357, + 0.004877906758338213, + -0.0713806077837944 + ] + }, + { + "id": "/en/downfall", + "initial_release_date": "2004-09-08", + "name": "Downfall", + "directed_by": [ + "Oliver Hirschbiegel" + ], + "genre": [ + "Biographical film", + "War film", + "Historical drama", + "Drama" + ], + "film_vector": [ + -0.3588809370994568, + -0.022881202399730682, + -0.08730067312717438, + -0.21932587027549744, + -0.008571777492761612, + -0.298511803150177, + -0.1227237731218338, + 0.10958239436149597, + -0.07487284392118454, + -0.1741274893283844 + ] + }, + { + "id": "/en/dr_dolittle_2", + "initial_release_date": "2001-06-19", + "name": "Dr. Dolittle 2", + "directed_by": [ + "Steve Carr" + ], + "genre": [ + "Family", + "Fantasy Comedy", + "Comedy", + "Romance Film" + ], + "film_vector": [ + -0.15368367731571198, + -0.007420167326927185, + -0.34031033515930176, + 0.29707586765289307, + 0.10758251696825027, + -0.054303087294101715, + 0.012624800205230713, + -0.06573314219713211, + -0.038388364017009735, + -0.27185553312301636 + ] + }, + { + "id": "/en/dr_dolittle_3", + "initial_release_date": "2006-04-25", + "name": "Dr. Dolittle 3", + "directed_by": [ + "Rich Thorne" + ], + "genre": [ + "Family", + "Comedy" + ], + "film_vector": [ + 0.09855473786592484, + -0.05676313489675522, + -0.28990232944488525, + 0.25631678104400635, + 0.13689154386520386, + -0.09987292438745499, + 0.10981972515583038, + -0.13859817385673523, + -0.068235844373703, + -0.22629761695861816 + ] + }, + { + "id": "/en/dracula_pages_from_a_virgins_diary", + "initial_release_date": "2002-02-28", + "name": "Dracula: Pages from a Virgin's Diary", + "directed_by": [ + "Guy Maddin" + ], + "genre": [ + "Silent film", + "Indie film", + "Horror", + "Musical", + "Experimental film", + "Dance film", + "Horror comedy", + "Musical comedy", + "Comedy" + ], + "film_vector": [ + -0.3495522439479828, + -0.10210198909044266, + -0.2477659285068512, + 0.15318144857883453, + -0.0452878437936306, + -0.22030365467071533, + 0.07743240147829056, + 0.2753469944000244, + 0.16293753683567047, + -0.2333957850933075 + ] + }, + { + "id": "/en/dragon_boys", + "name": "Dragon Boys", + "directed_by": [ + "Jerry Ciccoritti" + ], + "genre": [ + "Crime Drama", + "Ensemble Film", + "Drama" + ], + "film_vector": [ + -0.19080358743667603, + -0.015915628522634506, + -0.10676486790180206, + 0.0764913484454155, + 0.0850016176700592, + -0.005783092230558395, + -0.14865782856941223, + -0.09675182402133942, + 0.016693904995918274, + -0.13322165608406067 + ] + }, + { + "id": "/en/dragon_tiger_gate", + "initial_release_date": "2006-07-27", + "name": "Dragon Tiger Gate", + "directed_by": [ + "Wilson Yip" + ], + "genre": [ + "Martial Arts Film", + "Wuxia", + "Action/Adventure", + "Action Film", + "Thriller", + "Superhero movie", + "World cinema", + "Action Thriller", + "Chinese Movies" + ], + "film_vector": [ + -0.5348905324935913, + -0.00658330088481307, + -0.05842525139451027, + 0.26258385181427, + -0.11332240700721741, + -0.1564953327178955, + -0.17697882652282715, + -0.0048454334028065205, + -0.048886559903621674, + -0.015528366900980473 + ] + }, + { + "id": "/en/dragonfly_2002", + "initial_release_date": "2002-02-18", + "name": "Dragonfly", + "directed_by": [ + "Tom Shadyac" + ], + "genre": [ + "Thriller", + "Mystery", + "Romance Film", + "Fantasy", + "Drama" + ], + "film_vector": [ + -0.5145691633224487, + -0.08125685900449753, + -0.17714163661003113, + 0.2149963080883026, + 0.0771985575556755, + 0.059036001563072205, + -0.14528247714042664, + 0.003984622657299042, + 0.04733967408537865, + -0.11406644433736801 + ] + }, + { + "id": "/en/dragonlance_dragons_of_autumn_twilight", + "initial_release_date": "2008-01-15", + "name": "Dragonlance: Dragons of Autumn Twilight", + "directed_by": [ + "Will Meugniot" + ], + "genre": [ + "Animation", + "Sword and sorcery", + "Fantasy", + "Adventure Film", + "Science Fiction" + ], + "film_vector": [ + -0.3326440751552582, + 0.0429275818169117, + 0.12716104090213776, + 0.3523840308189392, + -0.23021173477172852, + 0.1452292650938034, + -0.22196276485919952, + 0.11247285455465317, + 0.10749442875385284, + -0.1888151466846466 + ] + }, + { + "id": "/en/drake_josh_go_hollywood", + "initial_release_date": "2006-01-06", + "name": "Drake & Josh Go Hollywood", + "directed_by": [ + "Adam Weissman", + "Steve Hoefer" + ], + "genre": [ + "Family", + "Adventure Film", + "Comedy" + ], + "film_vector": [ + -0.025833312422037125, + 0.03360344469547272, + -0.3078647255897522, + 0.27299731969833374, + 0.07705546170473099, + -0.06169081851840019, + -0.14516471326351166, + -0.21363243460655212, + 0.036223843693733215, + 0.06474260985851288 + ] + }, + { + "id": "/en/drawing_restraint_9", + "initial_release_date": "2005-07-01", + "name": "Drawing Restraint 9", + "directed_by": [ + "Matthew Barney" + ], + "genre": [ + "Cult film", + "Fantasy", + "Surrealism", + "Avant-garde", + "Experimental film", + "Japanese Movies" + ], + "film_vector": [ + -0.3980201482772827, + 0.08942969143390656, + 0.0256120003759861, + 0.13691799342632294, + -0.18579354882240295, + -0.17428243160247803, + 0.10853959619998932, + 0.05528775602579117, + 0.27646613121032715, + -0.14437928795814514 + ] + }, + { + "id": "/en/dreamcatcher", + "initial_release_date": "2003-03-06", + "name": "Dreamcatcher", + "directed_by": [ + "Lawrence Kasdan" + ], + "genre": [ + "Science Fiction", + "Horror", + "Thriller", + "Drama" + ], + "film_vector": [ + -0.44095104932785034, + -0.30658620595932007, + -0.09892114251852036, + 0.11114803701639175, + 0.03814074769616127, + 0.0834733173251152, + 0.019583627581596375, + -0.0031430437229573727, + 0.1983742117881775, + -0.16301506757736206 + ] + }, + { + "id": "/en/dreamer_2005", + "initial_release_date": "2005-09-10", + "name": "Dreamer", + "directed_by": [ + "John Gatins" + ], + "genre": [ + "Family", + "Sports", + "Drama" + ], + "film_vector": [ + 0.01881415769457817, + -0.029580768197774887, + -0.08527069538831711, + -0.1291235387325287, + -0.10225316882133484, + 0.2905944585800171, + -0.22978423535823822, + -0.15063926577568054, + 0.12293968349695206, + 0.0680973082780838 + ] + }, + { + "id": "/en/dreaming_of_julia", + "initial_release_date": "2003-10-24", + "name": "Dreaming of Julia", + "directed_by": [ + "Juan Gerard" + ], + "genre": [ + "Indie film", + "Action Film", + "Crime Fiction", + "Action/Adventure", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.4958555996417999, + -0.07611194998025894, + -0.29122787714004517, + 0.07743789255619049, + 0.06526121497154236, + -0.05860733985900879, + -0.10469909012317657, + -0.1701963245868683, + 0.2812058627605438, + -0.20066741108894348 + ] + }, + { + "id": "/en/driving_miss_wealthy_juet_sai_ho_bun", + "initial_release_date": "2004-05-03", + "name": "Driving Miss Wealthy", + "directed_by": [ + "James Yuen" + ], + "genre": [ + "Romance Film", + "World cinema", + "Romantic comedy", + "Chinese Movies", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.4427306354045868, + 0.25636160373687744, + -0.32131242752075195, + 0.03304975479841232, + 0.13814693689346313, + -0.1358858346939087, + -0.05640614777803421, + -0.13034160435199738, + 0.07586251199245453, + -0.1544836461544037 + ] + }, + { + "id": "/en/drowning_mona", + "initial_release_date": "2000-01-02", + "name": "Drowning Mona", + "directed_by": [ + "Nick Gomez" + ], + "genre": [ + "Black comedy", + "Mystery", + "Whodunit", + "Crime Comedy", + "Crime Fiction", + "Comedy" + ], + "film_vector": [ + -0.3205941915512085, + -0.19731205701828003, + -0.3771357536315918, + -0.17055092751979828, + -0.13538196682929993, + -0.05769948661327362, + 0.15212731063365936, + 0.09426712989807129, + 0.037305764853954315, + -0.3171280026435852 + ] + }, + { + "id": "/en/drugstore_girl", + "name": "Drugstore Girl", + "directed_by": [ + "Katsuhide Motoki" + ], + "genre": [ + "Japanese Movies", + "Comedy" + ], + "film_vector": [ + -0.19641900062561035, + 0.06317703425884247, + -0.26428085565567017, + 0.23608121275901794, + 0.2289622724056244, + -0.03138713911175728, + 0.22164398431777954, + -0.1731542944908142, + 0.17537671327590942, + -0.1972334384918213 + ] + }, + { + "id": "/en/druids", + "initial_release_date": "2001-08-31", + "name": "Druids", + "directed_by": [ + "Jacques Dorfmann" + ], + "genre": [ + "Adventure Film", + "War film", + "Action/Adventure", + "World cinema", + "Epic film", + "Historical Epic", + "Historical fiction", + "Biographical film", + "Drama" + ], + "film_vector": [ + -0.5063806176185608, + 0.04701893776655197, + -0.017341462895274162, + 0.26058122515678406, + -0.12305428832769394, + -0.2366243600845337, + -0.195829838514328, + 0.08136416971683502, + 0.0010820943862199783, + -0.24236756563186646 + ] + }, + { + "id": "/en/duck_the_carbine_high_massacre", + "initial_release_date": "2000-04-20", + "name": "Duck! The Carbine High Massacre", + "directed_by": [ + "William Hellfire", + "Joey Smack" + ], + "genre": [ + "Satire", + "Black comedy", + "Parody", + "Indie film", + "Teen film", + "Comedy" + ], + "film_vector": [ + -0.003690301440656185, + -0.16034984588623047, + -0.235327810049057, + 0.09435973316431046, + -0.08619849383831024, + -0.27534231543540955, + 0.12147684395313263, + 0.004285234957933426, + -0.049837883561849594, + -0.19872094690799713 + ] + }, + { + "id": "/en/dude_wheres_my_car", + "initial_release_date": "2000-12-10", + "name": "Dude, Where's My Car?", + "directed_by": [ + "Danny Leiner" + ], + "genre": [ + "Mystery", + "Comedy", + "Science Fiction" + ], + "film_vector": [ + -0.2711135745048523, + -0.14542916417121887, + -0.21355792880058289, + 0.13384994864463806, + -0.19820508360862732, + 0.0007850024849176407, + 0.06629716604948044, + -0.23608018457889557, + 0.06211645156145096, + -0.1016286313533783 + ] + }, + { + "id": "/en/dude_wheres_the_party", + "name": "Dude, Where's the Party?", + "directed_by": [ + "Benny Mathews" + ], + "genre": [ + "Indie film", + "Comedy of manners", + "Comedy" + ], + "film_vector": [ + -0.0879942923784256, + 0.05380206182599068, + -0.44773125648498535, + 0.07412655651569366, + -0.05583745986223221, + -0.26174041628837585, + 0.19091208279132843, + -0.10584420710802078, + 0.09217293560504913, + -0.06477942317724228 + ] + }, + { + "id": "/en/duets", + "initial_release_date": "2000-09-09", + "name": "Duets", + "directed_by": [ + "Bruce Paltrow" + ], + "genre": [ + "Musical", + "Musical Drama", + "Musical comedy", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.11639013886451721, + 0.15974831581115723, + -0.5876671075820923, + -0.06260925531387329, + -0.024433713406324387, + 0.009084067307412624, + -0.1523396372795105, + 0.2715490460395813, + -0.10496629774570465, + 0.04195302352309227 + ] + }, + { + "id": "/en/dumb_dumberer", + "initial_release_date": "2003-06-13", + "name": "Dumb & Dumberer: When Harry Met Lloyd", + "directed_by": [ + "Troy Miller" + ], + "genre": [ + "Buddy film", + "Teen film", + "Screwball comedy", + "Slapstick", + "Comedy" + ], + "film_vector": [ + -0.04764594882726669, + -0.006933171302080154, + -0.526317298412323, + 0.2653453052043915, + -0.06564293801784515, + -0.2626578211784363, + 0.14120003581047058, + -0.07401569932699203, + -0.09962308406829834, + -0.18342992663383484 + ] + }, + { + "id": "/en/dumm_dumm_dumm", + "initial_release_date": "2001-04-13", + "name": "Dumm Dumm Dumm", + "directed_by": [ + "Azhagam Perumal" + ], + "genre": [ + "Romance Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.36707359552383423, + 0.10056181997060776, + -0.3404974937438965, + 0.06665244698524475, + 0.12614215910434723, + -0.085276298224926, + 0.042939845472574234, + -0.11543525755405426, + 0.07929741591215134, + -0.12407270818948746 + ] + }, + { + "id": "/en/dummy_2003", + "initial_release_date": "2003-09-12", + "name": "Dummy", + "directed_by": [ + "Greg Pritikin" + ], + "genre": [ + "Romantic comedy", + "Indie film", + "Romance Film", + "Comedy", + "Comedy-drama", + "Drama" + ], + "film_vector": [ + -0.29179316759109497, + -0.01819823868572712, + -0.6352949142456055, + -0.018249519169330597, + 0.08678863942623138, + -0.172403022646904, + 0.028825899586081505, + 0.1414615511894226, + -0.0021458016708493233, + -0.07073787599802017 + ] + }, + { + "id": "/en/dumplings", + "initial_release_date": "2004-08-04", + "name": "Dumplings", + "directed_by": [ + "Fruit Chan" + ], + "genre": [ + "Horror", + "Drama" + ], + "film_vector": [ + 0.0733930915594101, + -0.04199407249689102, + -0.1321600079536438, + -0.19911687076091766, + 0.0419071689248085, + 0.1237126886844635, + 0.26086336374282837, + 0.09429971873760223, + 0.0813247412443161, + -0.057596396654844284 + ] + }, + { + "id": "/en/duplex", + "initial_release_date": "2003-09-26", + "name": "Duplex", + "directed_by": [ + "Danny DeVito" + ], + "genre": [ + "Black comedy", + "Comedy" + ], + "film_vector": [ + 0.05465714633464813, + -0.008110826835036278, + -0.35642439126968384, + -0.04267718642950058, + -0.08350562304258347, + -0.13531817495822906, + 0.3487090766429901, + -0.13054853677749634, + -0.069942407310009, + -0.12550599873065948 + ] + }, + { + "id": "/en/dus", + "initial_release_date": "2005-07-08", + "name": "Dus", + "directed_by": [ + "Anubhav Sinha" + ], + "genre": [ + "Thriller", + "Action Film", + "Crime Fiction", + "Bollywood" + ], + "film_vector": [ + -0.6732094287872314, + 0.02458016946911812, + -0.1025281697511673, + -0.05987885594367981, + -0.03786137327551842, + -0.0649409294128418, + 0.20218971371650696, + -0.17709515988826752, + -0.008765175938606262, + -0.035135120153427124 + ] + }, + { + "id": "/en/dust_2001", + "initial_release_date": "2001-08-29", + "name": "Dust", + "directed_by": [ + "Milcho Manchevski" + ], + "genre": [ + "Western", + "Drama" + ], + "film_vector": [ + -0.13458839058876038, + 0.012018285691738129, + -0.01253652572631836, + -0.09505156427621841, + 0.0663745179772377, + -0.08114036917686462, + -0.06789949536323547, + -0.05141379311680794, + -0.07569092512130737, + -0.23181729018688202 + ] + }, + { + "id": "/wikipedia/en_title/E_$0028film$0029", + "initial_release_date": "2006-10-21", + "name": "E", + "directed_by": [ + "S. P. Jananathan" + ], + "genre": [ + "Action Film", + "Thriller", + "Drama" + ], + "film_vector": [ + -0.6275852918624878, + -0.09378256648778915, + -0.19525378942489624, + 0.01479576900601387, + 0.03243647515773773, + -0.11897453665733337, + -0.019127149134874344, + -0.15567541122436523, + -0.011001162230968475, + -0.04964108020067215 + ] + }, + { + "id": "/en/earthlings", + "name": "Earthlings", + "directed_by": [ + "Shaun Monson" + ], + "genre": [ + "Documentary film", + "Nature", + "Culture & Society", + "Animal" + ], + "film_vector": [ + 0.01985434629023075, + 0.06349194049835205, + 0.13826043903827667, + 0.15375471115112305, + -0.0029316172003746033, + -0.21930164098739624, + -0.11429544538259506, + 0.041721221059560776, + 0.24618324637413025, + -0.01078435592353344 + ] + }, + { + "id": "/en/eastern_promises", + "initial_release_date": "2007-09-08", + "name": "Eastern Promises", + "directed_by": [ + "David Cronenberg" + ], + "genre": [ + "Thriller", + "Crime Fiction", + "Mystery", + "Drama" + ], + "film_vector": [ + -0.4835476875305176, + -0.22247320413589478, + -0.2301115095615387, + -0.22616152465343475, + 0.026493819430470467, + 0.06025921553373337, + -0.11354969441890717, + -0.01961219310760498, + 0.06344196200370789, + -0.21198520064353943 + ] + }, + { + "id": "/en/eating_out", + "name": "Eating Out", + "directed_by": [ + "Q. Allan Brocka" + ], + "genre": [ + "Romantic comedy", + "LGBT", + "Gay Themed", + "Romance Film", + "Gay", + "Gay Interest", + "Comedy" + ], + "film_vector": [ + -0.21224504709243774, + 0.0806502103805542, + -0.5452171564102173, + 0.0770212709903717, + -0.12963919341564178, + -0.10307518392801285, + -0.023432958871126175, + 0.14402323961257935, + 0.06644925475120544, + -0.019746989011764526 + ] + }, + { + "id": "/en/echoes_of_innocence", + "initial_release_date": "2005-09-09", + "name": "Echoes of Innocence", + "directed_by": [ + "Nathan Todd Sims" + ], + "genre": [ + "Thriller", + "Romance Film", + "Christian film", + "Mystery", + "Supernatural", + "Drama" + ], + "film_vector": [ + -0.48842853307724, + -0.20867766439914703, + -0.25261932611465454, + 0.10659196972846985, + 0.20044927299022675, + -0.07546118646860123, + -0.0663713663816452, + 0.015590405091643333, + 0.22833320498466492, + -0.10812507569789886 + ] + }, + { + "id": "/en/eddies_million_dollar_cook_off", + "initial_release_date": "2003-07-18", + "name": "Eddie's Million Dollar Cook-Off", + "directed_by": [ + "Paul Hoen" + ], + "genre": [ + "Teen film" + ], + "film_vector": [ + 0.13586093485355377, + -0.12210257351398468, + -0.1590561866760254, + 0.15323993563652039, + 0.138564333319664, + -0.11703571677207947, + -0.0471947118639946, + -0.19441892206668854, + 0.009283693507313728, + 0.009446577169001102 + ] + }, + { + "id": "/en/edison_2006", + "initial_release_date": "2005-03-05", + "name": "Edison", + "directed_by": [ + "David J. Burke" + ], + "genre": [ + "Thriller", + "Crime Fiction", + "Mystery", + "Crime Thriller", + "Drama" + ], + "film_vector": [ + -0.505687952041626, + -0.33442944288253784, + -0.21580201387405396, + -0.19352512061595917, + -0.1569564789533615, + 0.08586185425519943, + -0.03260018303990364, + 0.0035183029249310493, + -0.053768448531627655, + -0.24469883739948273 + ] + }, + { + "id": "/en/edmond_2006", + "initial_release_date": "2005-09-02", + "name": "Edmond", + "directed_by": [ + "Stuart Gordon" + ], + "genre": [ + "Thriller", + "Psychological thriller", + "Indie film", + "Crime Fiction", + "Drama" + ], + "film_vector": [ + -0.5734878778457642, + -0.22446969151496887, + -0.33555471897125244, + -0.10361656546592712, + -0.02358778938651085, + -0.09649556875228882, + 0.0400419645011425, + -0.002137506380677223, + 0.13939478993415833, + -0.12851431965827942 + ] + }, + { + "id": "/en/eight_below", + "initial_release_date": "2006-02-17", + "name": "Eight Below", + "directed_by": [ + "Frank Marshall" + ], + "genre": [ + "Adventure Film", + "Family", + "Drama" + ], + "film_vector": [ + -0.32256048917770386, + 0.010214973241090775, + -0.21696703135967255, + 0.3559218645095825, + -0.03905105963349342, + -0.06339297443628311, + -0.14036141335964203, + -0.09513963758945465, + 0.040787845849990845, + -0.23849311470985413 + ] + }, + { + "id": "/en/eight_crazy_nights", + "directed_by": [ + "Seth Kearsley" + ], + "initial_release_date": "2002-11-27", + "genre": [ + "Christmas movie", + "Musical", + "Animation", + "Musical comedy", + "Comedy" + ], + "name": "Eight Crazy Nights", + "film_vector": [ + 0.04590002819895744, + 0.10355662554502487, + -0.35890474915504456, + 0.3133072555065155, + -0.03806464746594429, + -0.15863272547721863, + 0.007640299387276173, + 0.18331067264080048, + 0.06012873724102974, + -0.17234721779823303 + ] + }, + { + "id": "/en/eight_legged_freaks", + "directed_by": [ + "Ellory Elkayem" + ], + "initial_release_date": "2002-05-30", + "genre": [ + "Horror", + "Natural horror film", + "Science Fiction", + "Monster", + "B movie", + "Comedy", + "Action Film", + "Thriller", + "Horror comedy" + ], + "name": "Eight Legged Freaks", + "film_vector": [ + -0.31574201583862305, + -0.24833402037620544, + -0.2534586489200592, + 0.2774718701839447, + -0.024263760074973106, + -0.21592511236667633, + 0.20169520378112793, + 0.12308940291404724, + 0.08978185802698135, + -0.08644524216651917 + ] + }, + { + "id": "/en/ek_ajnabee", + "directed_by": [ + "Apoorva Lakhia" + ], + "initial_release_date": "2005-12-09", + "genre": [ + "Action Film", + "Thriller", + "Crime Fiction", + "Action Thriller", + "Drama", + "Bollywood" + ], + "name": "Ek Ajnabee", + "film_vector": [ + -0.5855863094329834, + 0.10687319189310074, + -0.13518157601356506, + -0.025707192718982697, + 0.059741877019405365, + -0.08639216423034668, + 0.09519221633672714, + -0.0786985456943512, + -0.09245944023132324, + 0.047724008560180664 + ] + }, + { + "id": "/en/eklavya_the_royal_guard", + "directed_by": [ + "Vidhu Vinod Chopra" + ], + "initial_release_date": "2007-02-16", + "genre": [ + "Historical drama", + "Romance Film", + "Musical", + "Epic film", + "Thriller", + "Bollywood", + "World cinema" + ], + "name": "Eklavya: The Royal Guard", + "film_vector": [ + -0.43048033118247986, + 0.249497652053833, + 0.0055821556597948074, + -0.005195599049329758, + 0.19628478586673737, + -0.14463727176189423, + -0.029513569548726082, + 0.029381707310676575, + -0.08380050212144852, + -0.09555448591709137 + ] + }, + { + "id": "/en/el_abrazo_partido", + "directed_by": [ + "Daniel Burman" + ], + "initial_release_date": "2004-02-09", + "genre": [ + "Indie film", + "Comedy", + "Comedy-drama", + "Drama" + ], + "name": "Lost Embrace", + "film_vector": [ + -0.24614429473876953, + -0.039163000881671906, + -0.3289751410484314, + -0.019992366433143616, + 0.07015381753444672, + -0.21547609567642212, + -0.00010267458856105804, + 0.023408163338899612, + 0.20777228474617004, + -0.13586866855621338 + ] + }, + { + "id": "/en/el_aura", + "directed_by": [ + "Fabi\u00e1n Bielinsky" + ], + "initial_release_date": "2005-09-15", + "genre": [ + "Thriller", + "Crime Fiction", + "Drama" + ], + "name": "El Aura", + "film_vector": [ + -0.47228366136550903, + -0.167436420917511, + -0.09250339865684509, + -0.12459386140108109, + -0.004824858158826828, + 0.10144828259944916, + -0.021362103521823883, + -0.04657038673758507, + 0.1274566501379013, + -0.23458519577980042 + ] + }, + { + "id": "/en/el_crimen_del_padre_amaro", + "directed_by": [ + "Carlos Carrera" + ], + "initial_release_date": "2002-08-16", + "genre": [ + "Romance Film", + "Drama" + ], + "name": "The Crime of Father Amaro", + "film_vector": [ + -0.205230712890625, + 0.0411686971783638, + -0.08339377492666245, + -0.05051927641034126, + 0.38475972414016724, + -0.05609153211116791, + -0.026414945721626282, + -0.13708776235580444, + -0.011095134541392326, + -0.16187255084514618 + ] + }, + { + "id": "/en/el_juego_de_arcibel", + "directed_by": [ + "Alberto Lecchi" + ], + "initial_release_date": "2003-05-29", + "genre": [ + "Indie film", + "Political drama", + "World cinema", + "Drama" + ], + "name": "El juego de Arcibel", + "film_vector": [ + -0.34076690673828125, + 0.11051148176193237, + -0.07873950153589249, + -0.1312543898820877, + -0.10985644161701202, + -0.211565300822258, + -0.05665016546845436, + -0.0066117472015321255, + 0.24953724443912506, + -0.14053910970687866 + ] + }, + { + "id": "/wikipedia/en_title/El_Muerto_$0028film$0029", + "directed_by": [ + "Brian Cox" + ], + "genre": [ + "Indie film", + "Supernatural", + "Thriller", + "Superhero movie", + "Action/Adventure" + ], + "name": "El Muerto", + "film_vector": [ + -0.3910564184188843, + -0.2904694974422455, + -0.2248903214931488, + 0.21562357246875763, + 0.16671015322208405, + -0.1820993721485138, + -0.05446440353989601, + -0.13749408721923828, + 0.1461676061153412, + -0.10385045409202576 + ] + }, + { + "id": "/en/el_principio_de_arquimedes", + "directed_by": [ + "Gerardo Herrero" + ], + "initial_release_date": "2004-03-26", + "genre": [ + "Drama" + ], + "name": "The Archimedes Principle", + "film_vector": [ + 0.07732780277729034, + 0.049411509186029434, + 0.06747748702764511, + -0.154842346906662, + -0.01595892943441868, + 0.023119112476706505, + -0.11901015043258667, + 0.11759574711322784, + -0.08312574028968811, + -0.019090553745627403 + ] + }, + { + "id": "/en/el_raton_perez", + "directed_by": [ + "Juan Pablo Buscarini" + ], + "initial_release_date": "2006-07-13", + "genre": [ + "Fantasy", + "Animation", + "Comedy", + "Family" + ], + "name": "The Hairy Tooth Fairy", + "film_vector": [ + 0.05767427384853363, + 0.042224638164043427, + -0.07149964570999146, + 0.4277500510215759, + -0.1244741827249527, + 0.15651006996631622, + 0.06648045778274536, + 0.12935708463191986, + 0.0991743803024292, + -0.3012981414794922 + ] + }, + { + "id": "/en/election_2005", + "directed_by": [ + "Johnnie To" + ], + "initial_release_date": "2005-05-14", + "genre": [ + "Crime Fiction", + "Thriller", + "Drama" + ], + "name": "Election", + "film_vector": [ + -0.3458906412124634, + -0.256765753030777, + -0.15894676744937897, + -0.33074256777763367, + -0.04670707508921623, + 0.03930925577878952, + -0.005711945705115795, + -0.08875613659620285, + -0.02178437076508999, + -0.11874189972877502 + ] + }, + { + "id": "/en/election_2", + "directed_by": [ + "Johnnie To" + ], + "initial_release_date": "2006-04-04", + "genre": [ + "Thriller", + "Crime Fiction", + "Drama" + ], + "name": "Election 2", + "film_vector": [ + -0.39835673570632935, + -0.26611077785491943, + -0.1901729851961136, + -0.19267058372497559, + -0.007726218551397324, + -0.011122886091470718, + -0.008406196720898151, + -0.1389106810092926, + -0.0026740729808807373, + -0.05543084442615509 + ] + }, + { + "id": "/en/daft_punks_electroma", + "directed_by": [ + "Thomas Bangalter", + "Guy-Manuel de Homem-Christo" + ], + "initial_release_date": "2006-05-21", + "genre": [ + "Indie film", + "Silent film", + "Science Fiction", + "World cinema", + "Avant-garde", + "Experimental film", + "Road movie", + "Drama" + ], + "name": "Daft Punk's Electroma", + "film_vector": [ + -0.3673628568649292, + 0.030846714973449707, + -0.11771240830421448, + 0.06427154690027237, + -0.2186025083065033, + -0.33091968297958374, + -0.022130632773041725, + 0.07271070033311844, + 0.27716895937919617, + 0.08436638861894608 + ] + }, + { + "id": "/en/elektra_2005", + "directed_by": [ + "Rob Bowman" + ], + "initial_release_date": "2005-01-08", + "genre": [ + "Action Film", + "Action/Adventure", + "Martial Arts Film", + "Superhero movie", + "Thriller", + "Fantasy", + "Crime Fiction" + ], + "name": "Elektra", + "film_vector": [ + -0.6298211812973022, + -0.12204883247613907, + -0.14108985662460327, + 0.23089052736759186, + -0.07923920452594757, + -0.06418926268815994, + -0.14457671344280243, + -0.06878483295440674, + -0.02448079362511635, + -0.09920793771743774 + ] + }, + { + "id": "/en/elephant_2003", + "directed_by": [ + "Gus Van Sant" + ], + "initial_release_date": "2003-05-18", + "genre": [ + "Teen film", + "Indie film", + "Crime Fiction", + "Thriller", + "Drama" + ], + "name": "Elephant", + "film_vector": [ + -0.4889753460884094, + -0.06300806254148483, + -0.1792677938938141, + 0.1426084190607071, + 0.005936766974627972, + -0.18327835202217102, + 0.047344230115413666, + -0.1300540566444397, + 0.1633182168006897, + -0.06430414319038391 + ] + }, + { + "id": "/en/elephants_dream", + "directed_by": [ + "Bassam Kurdali" + ], + "initial_release_date": "2006-03-24", + "genre": [ + "Short Film", + "Computer Animation" + ], + "name": "Elephants Dream", + "film_vector": [ + 0.08002207428216934, + 0.15675601363182068, + 0.2038332223892212, + 0.2714223265647888, + 0.07975966483354568, + -0.18621307611465454, + 0.02762266807258129, + 0.046305641531944275, + 0.1788926124572754, + -0.04245462268590927 + ] + }, + { + "id": "/en/elf_2003", + "directed_by": [ + "Jon Favreau" + ], + "initial_release_date": "2003-10-09", + "genre": [ + "Family", + "Romance Film", + "Comedy", + "Fantasy" + ], + "name": "Elf", + "film_vector": [ + -0.030004605650901794, + 0.0555853545665741, + -0.1868339478969574, + 0.37941569089889526, + 0.07621755450963974, + 0.05328197032213211, + -0.04672764986753464, + 0.07748626172542572, + 0.13524216413497925, + -0.36147990822792053 + ] + }, + { + "id": "/en/elizabethtown_2005", + "directed_by": [ + "Cameron Crowe" + ], + "initial_release_date": "2005-09-04", + "genre": [ + "Romantic comedy", + "Romance Film", + "Family Drama", + "Comedy-drama", + "Comedy", + "Drama" + ], + "name": "Elizabethtown", + "film_vector": [ + -0.2805476784706116, + 0.05573144927620888, + -0.5791829824447632, + -0.02511219121515751, + 0.03152729943394661, + -0.06573610007762909, + -0.17258885502815247, + 0.17528514564037323, + -0.062346793711185455, + -0.23246970772743225 + ] + }, + { + "id": "/en/elviras_haunted_hills", + "directed_by": [ + "Sam Irvin" + ], + "initial_release_date": "2001-06-23", + "genre": [ + "Parody", + "Horror", + "Cult film", + "Haunted House Film", + "Horror comedy", + "Comedy" + ], + "name": "Elvira's Haunted Hills", + "film_vector": [ + -0.12072338163852692, + -0.22959086298942566, + -0.2202376127243042, + 0.16367605328559875, + 0.10371863842010498, + -0.18806563317775726, + 0.24496129155158997, + 0.25740331411361694, + 0.09230662882328033, + -0.11650480329990387 + ] + }, + { + "id": "/en/elvis_has_left_the_building_2004", + "directed_by": [ + "Joel Zwick" + ], + "genre": [ + "Action Film", + "Action/Adventure", + "Road movie", + "Crime Comedy", + "Crime Fiction", + "Comedy" + ], + "name": "Elvis Has Left the Building", + "film_vector": [ + -0.17566725611686707, + -0.10536857694387436, + -0.2641697824001312, + 0.02635803259909153, + -0.03906118869781494, + -0.21215376257896423, + 0.01031359750777483, + -0.048566050827503204, + -0.08131673187017441, + -0.0727853998541832 + ] + }, + { + "id": "/en/empire_2002", + "directed_by": [ + "Franc. Reyes" + ], + "genre": [ + "Thriller", + "Crime Fiction", + "Indie film", + "Action", + "Drama", + "Action Thriller" + ], + "name": "Empire", + "film_vector": [ + -0.6331177949905396, + -0.18608418107032776, + -0.274236261844635, + -0.04723326489329338, + -0.11620567739009857, + -0.128154456615448, + -0.09327493607997894, + -0.08895961940288544, + 0.009396450594067574, + -0.12120990455150604 + ] + }, + { + "id": "/en/employee_of_the_month_2004", + "directed_by": [ + "Mitch Rouse" + ], + "initial_release_date": "2004-01-17", + "genre": [ + "Black comedy", + "Indie film", + "Heist film", + "Comedy" + ], + "name": "Employee of the Month", + "film_vector": [ + -0.2402341365814209, + -0.1187426745891571, + -0.42939871549606323, + 0.009517988190054893, + -0.009642653167247772, + -0.3306818902492523, + 0.15387240052223206, + -0.22758644819259644, + 0.018708104267716408, + -0.09364929795265198 + ] + }, + { + "id": "/en/employee_of_the_month", + "directed_by": [ + "Greg Coolidge" + ], + "initial_release_date": "2006-10-06", + "genre": [ + "Romantic comedy", + "Romance Film", + "Comedy" + ], + "name": "Employee of the Month", + "film_vector": [ + -0.2591629922389984, + 0.09644217789173126, + -0.5145017504692078, + 0.054166279733181, + 0.19893109798431396, + -0.10818297415971756, + 0.030553564429283142, + -0.11810660362243652, + 0.017378563061356544, + -0.124554842710495 + ] + }, + { + "id": "/en/empress_chung", + "directed_by": [ + "Nelson Shin" + ], + "initial_release_date": "2005-08-12", + "genre": [ + "Animation", + "Children's/Family", + "East Asian cinema", + "World cinema" + ], + "name": "Empress Chung", + "film_vector": [ + -0.24217599630355835, + 0.2701180577278137, + 0.036906301975250244, + 0.22440922260284424, + -0.10730873048305511, + -0.055102262645959854, + -0.02787906304001808, + 0.018198320642113686, + 0.2851524353027344, + -0.3213652968406677 + ] + }, + { + "id": "/en/emr", + "directed_by": [ + "Danny McCullough", + "James Erskine" + ], + "initial_release_date": "2004-03-08", + "genre": [ + "Thriller", + "Mystery", + "Psychological thriller" + ], + "name": "EMR", + "film_vector": [ + -0.49567437171936035, + -0.35393619537353516, + -0.1807485669851303, + -0.09259787201881409, + 0.16328085958957672, + 0.0072410814464092255, + 0.07886945456266403, + -0.034166119992733, + 0.06624806672334671, + -0.0488576740026474 + ] + }, + { + "id": "/en/en_route", + "directed_by": [ + "Jan Kr\u00fcger" + ], + "initial_release_date": "2004-06-17", + "genre": [ + "Drama" + ], + "name": "En Route", + "film_vector": [ + 0.038409676402807236, + -0.027680855244398117, + -0.10375919193029404, + -0.2703493535518646, + 0.09279835969209671, + 0.1328514814376831, + -0.1523808240890503, + 0.0024510230869054794, + -0.08573272824287415, + 0.04104512184858322 + ] + }, + { + "id": "/en/enakku_20_unakku_18", + "directed_by": [ + "Jyothi Krishna" + ], + "initial_release_date": "2003-12-19", + "genre": [ + "Musical", + "Romance Film", + "Drama", + "Musical Drama" + ], + "name": "Enakku 20 Unakku 18", + "film_vector": [ + -0.37159961462020874, + 0.25656965374946594, + -0.24553915858268738, + 0.0822608470916748, + 0.10047237575054169, + -0.03254995495080948, + -0.042211342602968216, + 0.08608337491750717, + 0.14076325297355652, + 0.029186908155679703 + ] + }, + { + "id": "/en/enchanted_2007", + "directed_by": [ + "Kevin Lima" + ], + "initial_release_date": "2007-10-20", + "genre": [ + "Musical", + "Fantasy", + "Romance Film", + "Family", + "Comedy", + "Animation", + "Adventure Film", + "Drama", + "Musical comedy", + "Musical Drama" + ], + "name": "Enchanted", + "film_vector": [ + -0.35661327838897705, + 0.12109328806400299, + -0.439888060092926, + 0.317282497882843, + -0.13041768968105316, + 0.03005841001868248, + -0.23717132210731506, + 0.2793062925338745, + 0.05302908271551132, + -0.1232834905385971 + ] + }, + { + "id": "/en/end_of_the_spear", + "directed_by": [ + "Jim Hanon" + ], + "genre": [ + "Docudrama", + "Christian film", + "Indie film", + "Adventure Film", + "Historical period drama", + "Action/Adventure", + "Inspirational Drama", + "Drama" + ], + "name": "End of the Spear", + "film_vector": [ + -0.4176132380962372, + -0.03481651097536087, + -0.17027954757213593, + 0.050201013684272766, + -0.061587169766426086, + -0.3446485996246338, + -0.22988788783550262, + 0.05471000075340271, + 0.06304765492677689, + -0.17509868741035461 + ] + }, + { + "id": "/en/enduring_love", + "directed_by": [ + "Roger Michell" + ], + "initial_release_date": "2004-09-04", + "genre": [ + "Thriller", + "Mystery", + "Film adaptation", + "Indie film", + "Romance Film", + "Psychological thriller", + "Drama" + ], + "name": "Enduring Love", + "film_vector": [ + -0.542782187461853, + -0.10416668653488159, + -0.38587456941604614, + 0.05605607107281685, + 0.20843631029129028, + -0.17019294202327728, + -0.07927507162094116, + 0.003074187785387039, + 0.09392006695270538, + -0.04425715282559395 + ] + }, + { + "id": "/en/enemy_at_the_gates", + "directed_by": [ + "Jean-Jacques Annaud" + ], + "initial_release_date": "2001-02-07", + "genre": [ + "War film", + "Romance Film", + "Action Film", + "Historical fiction", + "Thriller", + "Drama" + ], + "name": "Enemy at the Gates", + "film_vector": [ + -0.5317107439041138, + -0.1733996719121933, + -0.15433140099048615, + 0.014548927545547485, + 0.00100729800760746, + -0.22084271907806396, + -0.18624715507030487, + 0.05630966275930405, + -0.08023194223642349, + -0.14758116006851196 + ] + }, + { + "id": "/en/enigma_2001", + "directed_by": [ + "Michael Apted" + ], + "initial_release_date": "2001-01-22", + "genre": [ + "Thriller", + "War film", + "Spy film", + "Romance Film", + "Mystery", + "Drama" + ], + "name": "Enigma", + "film_vector": [ + -0.6032161712646484, + -0.16238689422607422, + -0.2248222529888153, + 0.006877772510051727, + 0.1361117660999298, + -0.17616111040115356, + -0.07073277235031128, + 0.049881383776664734, + -0.04970685392618179, + -0.14228865504264832 + ] + }, + { + "id": "/en/enigma_the_best_of_jeff_hardy", + "directed_by": [ + "Craig Leathers" + ], + "initial_release_date": "2005-10-04", + "genre": [ + "Sports", + "Action Film" + ], + "name": "Enigma: The Best of Jeff Hardy", + "film_vector": [ + -0.08133195340633392, + -0.29101768136024475, + -0.028246674686670303, + 0.06209773197770119, + 0.07188583165407181, + -0.16283506155014038, + -0.07438928633928299, + -0.22373801469802856, + -0.085150346159935, + 0.04402165859937668 + ] + }, + { + "id": "/en/enron_the_smartest_guys_in_the_room", + "directed_by": [ + "Alex Gibney" + ], + "initial_release_date": "2005-04-22", + "genre": [ + "Documentary film", + "Indie film", + "Crime Fiction", + "Business", + "Culture & Society", + "Finance & Investing", + "Law & Crime", + "Biographical film" + ], + "name": "Enron: The Smartest Guys in the Room", + "film_vector": [ + -0.315951406955719, + -0.11373540759086609, + -0.21148502826690674, + -0.08948710560798645, + -0.17200763523578644, + -0.31555819511413574, + -0.11475667357444763, + -0.15244430303573608, + 0.017687803134322166, + -0.08104397356510162 + ] + }, + { + "id": "/en/envy_2004", + "directed_by": [ + "Barry Levinson" + ], + "initial_release_date": "2004-04-30", + "genre": [ + "Black comedy", + "Cult film", + "Comedy" + ], + "name": "Envy", + "film_vector": [ + -0.06681045144796371, + 0.00718824053183198, + -0.24761711061000824, + -0.0431332029402256, + -0.03542618080973625, + -0.2727676033973694, + 0.22090792655944824, + -0.00659363716840744, + 0.03264246881008148, + -0.2856067717075348 + ] + }, + { + "id": "/en/equilibrium_2002", + "directed_by": [ + "Kurt Wimmer" + ], + "initial_release_date": "2002-12-06", + "genre": [ + "Science Fiction", + "Dystopia", + "Future noir", + "Thriller", + "Action Film", + "Drama" + ], + "name": "Equilibrium", + "film_vector": [ + -0.5053919553756714, + -0.18658578395843506, + -0.20509259402751923, + -0.11101463437080383, + -0.0929984599351883, + -0.07790202647447586, + -0.055175311863422394, + -0.0829729288816452, + 0.08568394184112549, + -0.04576420038938522 + ] + }, + { + "id": "/en/eragon_2006", + "directed_by": [ + "Stefen Fangmeier" + ], + "initial_release_date": "2006-12-13", + "genre": [ + "Family", + "Adventure Film", + "Fantasy", + "Sword and sorcery", + "Action Film", + "Drama" + ], + "name": "Eragon", + "film_vector": [ + -0.3321133255958557, + 0.03318355605006218, + -0.08457915484905243, + 0.26031169295310974, + -0.07791769504547119, + 0.08640950918197632, + -0.25328224897384644, + 0.14602963626384735, + -0.005147548858076334, + -0.24711090326309204 + ] + }, + { + "id": "/en/erin_brockovich_2000", + "directed_by": [ + "Steven Soderbergh" + ], + "initial_release_date": "2000-03-14", + "genre": [ + "Biographical film", + "Legal drama", + "Trial drama", + "Romance Film", + "Docudrama", + "Comedy-drama", + "Feminist Film", + "Drama", + "Drama film" + ], + "name": "Erin Brockovich", + "film_vector": [ + -0.4891052842140198, + -0.06885384023189545, + -0.41418904066085815, + -0.08838433772325516, + -0.12948136031627655, + -0.24268001317977905, + -0.2078985571861267, + 0.0587148517370224, + -0.007385613396763802, + -0.07342208921909332 + ] + }, + { + "id": "/en/eros_2004", + "directed_by": [ + "Michelangelo Antonioni", + "Steven Soderbergh", + "Wong Kar-wai" + ], + "initial_release_date": "2004-09-10", + "genre": [ + "Romance Film", + "Erotica", + "Drama" + ], + "name": "Eros", + "film_vector": [ + -0.3245595097541809, + 0.07646648585796356, + -0.1826711744070053, + 0.016480594873428345, + 0.22969141602516174, + 0.04801514744758606, + -0.050867773592472076, + 0.07039891928434372, + 0.162167489528656, + -0.18187004327774048 + ] + }, + { + "id": "/en/escaflowne", + "directed_by": [ + "Kazuki Akane" + ], + "initial_release_date": "2000-06-24", + "genre": [ + "Adventure Film", + "Science Fiction", + "Fantasy", + "Animation", + "Romance Film", + "Action Film", + "Thriller", + "Drama" + ], + "name": "Escaflowne", + "film_vector": [ + -0.5660764575004578, + -0.0006551602855324745, + -0.13536058366298676, + 0.29225632548332214, + -0.11620303988456726, + -0.05141187086701393, + -0.11826519668102264, + -0.061303623020648956, + 0.1746213138103485, + -0.10698240995407104 + ] + }, + { + "id": "/en/escape_2006", + "directed_by": [ + "Niki Karimi" + ], + "genre": [ + "Drama" + ], + "name": "A Few Days Later", + "film_vector": [ + 0.11751651018857956, + 0.04441569745540619, + -0.16076816618442535, + -0.2358594834804535, + 0.19457319378852844, + 0.2238805592060089, + -0.08302313089370728, + -0.01156018115580082, + -0.03518562391400337, + 0.10519899427890778 + ] + }, + { + "id": "/en/eternal_sunshine_of_the_spotless_mind", + "directed_by": [ + "Michel Gondry" + ], + "initial_release_date": "2004-03-19", + "genre": [ + "Romance Film", + "Science Fiction", + "Drama" + ], + "name": "Eternal Sunshine of the Spotless Mind", + "film_vector": [ + -0.35573917627334595, + -0.013670600950717926, + -0.3194831609725952, + 0.1889146864414215, + 0.16077198088169098, + -0.18382754921913147, + -0.1553185135126114, + -0.03801732137799263, + 0.060696348547935486, + -0.21743977069854736 + ] + }, + { + "id": "/en/eulogy_2004", + "directed_by": [ + "Michael Clancy" + ], + "initial_release_date": "2004-10-15", + "genre": [ + "LGBT", + "Black comedy", + "Indie film", + "Comedy" + ], + "name": "Eulogy", + "film_vector": [ + -0.13279801607131958, + 0.06476931273937225, + -0.41132843494415283, + -0.04547185078263283, + -0.1994275152683258, + -0.1465170532464981, + 0.1839715838432312, + -0.0724153071641922, + 0.22438295185565948, + -0.11872497200965881 + ] + }, + { + "id": "/en/eurotrip", + "directed_by": [ + "Jeff Schaffer", + "Alec Berg", + "David Mandel" + ], + "initial_release_date": "2004-02-20", + "genre": [ + "Sex comedy", + "Adventure Film", + "Teen film", + "Comedy" + ], + "name": "EuroTrip", + "film_vector": [ + -0.22549261152744293, + 0.039143696427345276, + -0.40880638360977173, + 0.21613425016403198, + 0.08640076965093613, + -0.18416856229305267, + 0.04280191659927368, + -0.033771611750125885, + 0.10305589437484741, + -0.14379602670669556 + ] + }, + { + "id": "/en/evan_almighty", + "directed_by": [ + "Tom Shadyac" + ], + "initial_release_date": "2007-06-21", + "genre": [ + "Religious Film", + "Parody", + "Family", + "Fantasy", + "Fantasy Comedy", + "Heavenly Comedy", + "Comedy" + ], + "name": "Evan Almighty", + "film_vector": [ + -0.01940297521650791, + 0.022800123319029808, + -0.2919917404651642, + 0.16035035252571106, + -0.11832119524478912, + -0.16952475905418396, + 0.015982016921043396, + 0.1487259864807129, + -0.08169335126876831, + -0.10948026180267334 + ] + }, + { + "id": "/en/everlasting_regret", + "directed_by": [ + "Stanley Kwan" + ], + "initial_release_date": "2005-09-08", + "genre": [ + "Romance Film", + "Chinese Movies", + "Drama" + ], + "name": "Everlasting Regret", + "film_vector": [ + -0.28633981943130493, + 0.16480615735054016, + -0.17488272488117218, + 0.09569668024778366, + 0.33228057622909546, + -0.08507057279348373, + -0.06456805765628815, + -0.047753531485795975, + 0.12261900305747986, + -0.1684730052947998 + ] + }, + { + "id": "/en/everybody_famous", + "directed_by": [ + "Dominique Deruddere" + ], + "initial_release_date": "2000-04-12", + "genre": [ + "World cinema", + "Comedy", + "Drama" + ], + "name": "Everybody's Famous!", + "film_vector": [ + -0.2690001428127289, + 0.20616963505744934, + -0.19426248967647552, + 0.08143388479948044, + -0.1414361596107483, + -0.17610427737236023, + 0.0257889237254858, + -0.11797760426998138, + 0.21360737085342407, + -0.21224521100521088 + ] + }, + { + "id": "/en/everymans_feast", + "directed_by": [ + "Fritz Lehner" + ], + "initial_release_date": "2002-01-25", + "genre": [ + "Drama" + ], + "name": "Everyman's Feast", + "film_vector": [ + 0.17491498589515686, + 0.0026169531047344208, + -0.09807800501585007, + -0.21568109095096588, + 0.049814216792583466, + 0.02436971850693226, + -0.014496563002467155, + 0.1577787548303604, + -0.07619288563728333, + -0.05963008850812912 + ] + }, + { + "id": "/en/everyones_hero", + "directed_by": [ + "Christopher Reeve", + "Daniel St. Pierre", + "Colin Brady" + ], + "initial_release_date": "2006-09-15", + "genre": [ + "Computer Animation", + "Family", + "Animation", + "Adventure Film", + "Sports", + "Children's/Family", + "Family-Oriented Adventure" + ], + "name": "Everyone's Hero", + "film_vector": [ + -0.2665777802467346, + 0.035606227815151215, + -0.09322232007980347, + 0.4309405982494354, + -0.40646201372146606, + 0.17480316758155823, + -0.17374223470687866, + -0.13640692830085754, + 0.07010842859745026, + -0.06941258162260056 + ] + }, + { + "id": "/en/everything_2005", + "directed_by": [], + "initial_release_date": "2005-11-22", + "genre": [ + "Music video" + ], + "name": "Everything", + "film_vector": [ + 0.04928380995988846, + 0.058841973543167114, + -0.03626430034637451, + 0.04762764647603035, + 0.11588436365127563, + -0.1511780321598053, + -0.032322946935892105, + -0.00616234727203846, + 0.26573723554611206, + 0.23653091490268707 + ] + }, + { + "id": "/en/everything_goes", + "directed_by": [ + "Andrew Kotatko" + ], + "initial_release_date": "2004-06-14", + "genre": [ + "Short Film", + "Drama" + ], + "name": "Everything Goes", + "film_vector": [ + -0.2310793697834015, + 0.17466618120670319, + -0.1530618965625763, + -0.07490493357181549, + -0.0471489280462265, + -0.18454070389270782, + -0.015298282727599144, + -0.14413700997829437, + 0.2584116458892822, + -0.0884404107928276 + ] + }, + { + "id": "/en/everything_is_illuminated_2005", + "directed_by": [ + "Liev Schreiber" + ], + "initial_release_date": "2005-09-16", + "genre": [ + "Adventure Film", + "Film adaptation", + "Family Drama", + "Comedy-drama", + "Road movie", + "Comedy", + "Drama" + ], + "name": "Everything Is Illuminated", + "film_vector": [ + -0.2931177318096161, + 0.01356254331767559, + -0.30046048760414124, + 0.13699057698249817, + -0.08919339627027512, + -0.20182140171527863, + -0.09034265577793121, + 0.11403273791074753, + 0.077405646443367, + -0.11702325940132141 + ] + }, + { + "id": "/en/evilenko", + "directed_by": [ + "David Grieco" + ], + "initial_release_date": "2004-04-16", + "genre": [ + "Thriller", + "Horror", + "Crime Fiction" + ], + "name": "Evilenko", + "film_vector": [ + -0.49367254972457886, + -0.3033822774887085, + -0.06930704414844513, + -0.0964069813489914, + 0.05597178637981415, + 0.09901648759841919, + 0.19556096196174622, + 0.009184297174215317, + 0.09523440152406693, + -0.26227062940597534 + ] + }, + { + "id": "/en/evolution_2001", + "directed_by": [ + "Ivan Reitman" + ], + "initial_release_date": "2001-06-08", + "genre": [ + "Science Fiction", + "Parody", + "Action Film", + "Action/Adventure", + "Comedy" + ], + "name": "Evolution", + "film_vector": [ + -0.2563638985157013, + -0.017862526699900627, + -0.10237627476453781, + 0.26910924911499023, + -0.43797117471694946, + -0.07997394353151321, + 0.08576210588216782, + -0.05503038316965103, + 0.025193532928824425, + -0.06903155148029327 + ] + }, + { + "id": "/en/exit_wounds", + "directed_by": [ + "Andrzej Bartkowiak" + ], + "initial_release_date": "2001-03-16", + "genre": [ + "Action Film", + "Mystery", + "Martial Arts Film", + "Action/Adventure", + "Thriller", + "Crime Fiction" + ], + "name": "Exit Wounds", + "film_vector": [ + -0.48239365220069885, + -0.2709697186946869, + -0.2201012372970581, + 0.03000531904399395, + 0.056910209357738495, + -0.16383808851242065, + -0.06924840807914734, + -0.1056242361664772, + -0.04167784005403519, + -0.031049460172653198 + ] + }, + { + "id": "/en/exorcist_the_beginning", + "directed_by": [ + "Renny Harlin" + ], + "initial_release_date": "2004-08-18", + "genre": [ + "Horror", + "Supernatural", + "Psychological thriller", + "Cult film", + "Historical period drama" + ], + "name": "Exorcist: The Beginning", + "film_vector": [ + -0.4003523588180542, + -0.2915841341018677, + -0.10324029624462128, + 0.1275176852941513, + 0.04306256026029587, + -0.186387300491333, + 0.11791110783815384, + 0.16172699630260468, + 0.1288357377052307, + -0.1676395833492279 + ] + }, + { + "id": "/en/extreme_days", + "directed_by": [ + "Eric Hannah" + ], + "initial_release_date": "2001-09-28", + "genre": [ + "Comedy-drama", + "Action Film", + "Christian film", + "Action/Adventure", + "Road movie", + "Teen film", + "Sports" + ], + "name": "Extreme Days", + "film_vector": [ + -0.2731732726097107, + -0.12635211646556854, + -0.2677784264087677, + 0.261091411113739, + -0.06220334768295288, + -0.24672509729862213, + -0.12886174023151398, + -0.17364799976348877, + 0.04253023862838745, + 0.031014200299978256 + ] + }, + { + "id": "/en/extreme_ops", + "directed_by": [ + "Christian Duguay" + ], + "initial_release_date": "2002-11-27", + "genre": [ + "Action Film", + "Thriller", + "Action/Adventure", + "Sports", + "Adventure Film", + "Action Thriller", + "Chase Movie" + ], + "name": "Extreme Ops", + "film_vector": [ + -0.4706239402294159, + -0.2272154986858368, + -0.20202898979187012, + 0.19285547733306885, + -0.053935348987579346, + -0.26444751024246216, + -0.1537507027387619, + -0.04382152855396271, + -0.14421121776103973, + 0.11420115828514099 + ] + }, + { + "id": "/en/face_2004", + "directed_by": [ + "Yoo Sang-gon" + ], + "initial_release_date": "2004-06-11", + "genre": [ + "Horror", + "Thriller", + "Drama", + "East Asian cinema", + "World cinema" + ], + "name": "Face", + "film_vector": [ + -0.6020715832710266, + 0.0049095479771494865, + -0.04613013565540314, + 0.11113031953573227, + -0.07059475779533386, + -0.13833647966384888, + 0.19017696380615234, + -0.021959932520985603, + 0.26783668994903564, + -0.14699293673038483 + ] + }, + { + "id": "/en/la_finestra_di_fronte", + "directed_by": [ + "Ferzan \u00d6zpetek" + ], + "initial_release_date": "2003-02-28", + "genre": [ + "Romance Film", + "Drama" + ], + "name": "Facing Windows", + "film_vector": [ + -0.3053574860095978, + 0.06923295557498932, + -0.21318291127681732, + 0.016759809106588364, + 0.35076576471328735, + 0.011383533477783203, + -0.0877029299736023, + -0.0812956765294075, + 0.11322509497404099, + -0.09038347750902176 + ] + }, + { + "id": "/en/factory_girl", + "directed_by": [ + "George Hickenlooper" + ], + "initial_release_date": "2006-12-29", + "genre": [ + "Biographical film", + "Indie film", + "Historical period drama", + "Drama" + ], + "name": "Factory Girl", + "film_vector": [ + -0.291896253824234, + 0.11547546088695526, + -0.1936717927455902, + -0.11393781751394272, + 0.161455437541008, + -0.25061294436454773, + -0.13265906274318695, + -0.014914806000888348, + 0.2377416491508484, + -0.25053703784942627 + ] + }, + { + "id": "/en/fahrenheit_9_11", + "directed_by": [ + "Michael Moore" + ], + "initial_release_date": "2004-05-17", + "genre": [ + "Indie film", + "Documentary film", + "War film", + "Culture & Society", + "Crime Fiction", + "Drama" + ], + "name": "Fahrenheit 9/11", + "film_vector": [ + -0.4330233335494995, + -0.1210247203707695, + -0.22685402631759644, + -0.10714031755924225, + -0.22441008687019348, + -0.3601253628730774, + -0.12232799082994461, + -0.06830896437168121, + 0.24170862138271332, + -0.10801881551742554 + ] + }, + { + "id": "/en/fahrenheit_9_111_2", + "directed_by": [ + "Michael Moore" + ], + "genre": [ + "Documentary film" + ], + "name": "Fahrenheit 9/11\u00bd", + "film_vector": [ + 0.02721618115901947, + -0.16058146953582764, + 0.055642299354076385, + -0.10786080360412598, + 0.09895046055316925, + -0.37138116359710693, + -0.11388815939426422, + -0.04951917380094528, + 0.1652337610721588, + -0.0667373538017273 + ] + }, + { + "id": "/en/fail_safe_2000", + "directed_by": [ + "Stephen Frears" + ], + "initial_release_date": "2000-04-09", + "genre": [ + "Thriller", + "Science Fiction", + "Black-and-white", + "Film adaptation", + "Suspense", + "Psychological thriller", + "Political drama", + "Drama" + ], + "name": "Fail Safe", + "film_vector": [ + -0.5362285375595093, + -0.29023227095603943, + -0.3110775053501129, + -0.08484306186437607, + -0.050692472606897354, + -0.15719813108444214, + -0.013679715804755688, + 0.011463331058621407, + 0.03949876129627228, + -0.1079951748251915 + ] + }, + { + "id": "/en/failan", + "directed_by": [ + "Song Hae-sung" + ], + "initial_release_date": "2001-04-28", + "genre": [ + "Romance Film", + "World cinema", + "Drama" + ], + "name": "Failan", + "film_vector": [ + -0.4757632613182068, + 0.31176263093948364, + -0.16427043080329895, + -0.02428077720105648, + 0.18272119760513306, + -0.10470159351825714, + 0.024656228721141815, + -0.035580724477767944, + 0.11600813269615173, + -0.22433994710445404 + ] + }, + { + "id": "/en/failure_to_launch", + "directed_by": [ + "Tom Dey" + ], + "initial_release_date": "2006-03-10", + "genre": [ + "Romantic comedy", + "Romance Film", + "Comedy" + ], + "name": "Failure to Launch", + "film_vector": [ + -0.25445935130119324, + 0.1742861568927765, + -0.4305342435836792, + 0.05379631742835045, + 0.22500720620155334, + -0.10278661549091339, + 0.04788896068930626, + -0.05546393245458603, + 0.003803407773375511, + -0.07615967094898224 + ] + }, + { + "id": "/en/fake_2003", + "directed_by": [ + "Thanakorn Pongsuwan" + ], + "initial_release_date": "2003-04-28", + "genre": [ + "Romance Film" + ], + "name": "Fake", + "film_vector": [ + -0.12182401120662689, + 0.0024622920900583267, + -0.3285481333732605, + 0.010359175503253937, + 0.411110520362854, + -0.03230487182736397, + -0.03036123886704445, + -0.09504489600658417, + 0.11957176774740219, + -0.13106274604797363 + ] + }, + { + "id": "/en/falcons_2002", + "directed_by": [ + "Fri\u00f0rik \u00de\u00f3r Fri\u00f0riksson" + ], + "genre": [ + "Drama" + ], + "name": "Falcons", + "film_vector": [ + 0.15701249241828918, + -0.03384886682033539, + -0.05737894028425217, + -0.26605188846588135, + -0.020530279725790024, + 0.222262442111969, + -0.1858615279197693, + -0.05713355913758278, + -0.02610384300351143, + 0.10289882123470306 + ] + }, + { + "id": "/en/fallen_2006", + "directed_by": [ + "Mikael Salomon", + "Kevin Kerslake" + ], + "genre": [ + "Science Fiction", + "Fantasy", + "Action/Adventure", + "Drama" + ], + "name": "Fallen", + "film_vector": [ + -0.43190354108810425, + -0.13424883782863617, + -0.029658474028110504, + 0.0046715568751096725, + -0.2111806422472, + 0.17835354804992676, + -0.1239970475435257, + 0.0010198135860264301, + 0.1406061053276062, + -0.1845969557762146 + ] + }, + { + "id": "/en/family_-_ties_of_blood", + "directed_by": [ + "Rajkumar Santoshi" + ], + "initial_release_date": "2006-01-11", + "genre": [ + "Musical", + "Crime Fiction", + "Action Film", + "Romance Film", + "Thriller", + "Drama", + "Musical Drama" + ], + "name": "Family", + "film_vector": [ + -0.5585543513298035, + -0.04370516538619995, + -0.4858385920524597, + 0.022451311349868774, + -0.13828769326210022, + -0.08202646672725677, + -0.1432173252105713, + 0.008445050567388535, + 0.04945839196443558, + -0.05592700466513634 + ] + }, + { + "id": "/en/familywala", + "directed_by": [ + "Neeraj Vora" + ], + "genre": [ + "Comedy", + "Drama", + "Bollywood", + "World cinema" + ], + "name": "Familywala", + "film_vector": [ + -0.4727001190185547, + 0.4075571894645691, + -0.14546449482440948, + 0.036276742815971375, + -0.1402677446603775, + -0.022906530648469925, + 0.20990726351737976, + -0.19078505039215088, + 0.04451870173215866, + -0.1334112137556076 + ] + }, + { + "id": "/en/fan_chan", + "directed_by": [ + "Vitcha Gojiew", + "Witthaya Thongyooyong", + "Komgrit Triwimol", + "Nithiwat Tharathorn", + "Songyos Sugmakanan", + "Adisorn Tresirikasem" + ], + "initial_release_date": "2003-10-03", + "genre": [ + "Comedy", + "Romance Film" + ], + "name": "Fan Chan", + "film_vector": [ + -0.18965676426887512, + 0.09169338643550873, + -0.2743231952190399, + 0.19484813511371613, + 0.41921693086624146, + -0.03469479829072952, + 0.057467471808195114, + -0.1361543834209442, + 0.08303804695606232, + -0.13221167027950287 + ] + }, + { + "id": "/en/fanaa", + "directed_by": [ + "Kunal Kohli" + ], + "initial_release_date": "2006-05-26", + "genre": [ + "Thriller", + "Romance Film", + "Musical", + "Bollywood", + "Musical Drama", + "Drama" + ], + "name": "Fanaa", + "film_vector": [ + -0.6422045230865479, + 0.15149155259132385, + -0.25862976908683777, + 0.00221957266330719, + 0.03863011673092842, + -0.0049482062458992004, + 0.028421029448509216, + 0.026764851063489914, + 0.04285220056772232, + 0.04790990799665451 + ] + }, + { + "id": "/en/fantastic_four_2005", + "directed_by": [ + "Tim Story" + ], + "initial_release_date": "2005-06-29", + "genre": [ + "Fantasy", + "Science Fiction", + "Adventure Film", + "Action Film" + ], + "name": "Fantastic Four", + "film_vector": [ + -0.36177337169647217, + -0.10571920871734619, + -0.11344225704669952, + 0.3536139726638794, + -0.2034720480442047, + -0.007976368069648743, + -0.15152543783187866, + -0.06563786417245865, + -0.10243258625268936, + -0.12817168235778809 + ] + }, + { + "id": "/en/fantastic_four_and_the_silver_surfer", + "directed_by": [ + "Tim Story" + ], + "initial_release_date": "2007-06-12", + "genre": [ + "Fantasy", + "Science Fiction", + "Action Film", + "Thriller" + ], + "name": "Fantastic Four: Rise of the Silver Surfer", + "film_vector": [ + -0.3536847233772278, + -0.20924559235572815, + -0.16419631242752075, + 0.2947414219379425, + -0.17276760935783386, + -0.002911010757088661, + -0.15575656294822693, + -0.11618582904338837, + -0.12055960297584534, + -0.027941569685935974 + ] + }, + { + "id": "/en/fantastic_mr_fox_2007", + "directed_by": [ + "Wes Anderson" + ], + "initial_release_date": "2009-10-14", + "genre": [ + "Animation", + "Adventure Film", + "Comedy", + "Family" + ], + "name": "Fantastic Mr. Fox", + "film_vector": [ + -0.060655515640974045, + 0.05291776359081268, + -0.11478357017040253, + 0.5566692352294922, + -0.12436714768409729, + 0.03613754361867905, + -0.04857365041971207, + -0.13023412227630615, + 0.032525673508644104, + -0.200309157371521 + ] + }, + { + "id": "/en/faq_frequently_asked_questions", + "directed_by": [ + "Carlos Atanes" + ], + "initial_release_date": "2004-10-12", + "genre": [ + "Science Fiction" + ], + "name": "FAQ: Frequently Asked Questions", + "film_vector": [ + -0.164907306432724, + -0.03754079341888428, + 0.0990142896771431, + 0.0557839497923851, + -0.1986604481935501, + 0.103249691426754, + -0.1114487498998642, + -0.02006632089614868, + -0.05075037479400635, + -0.07495394349098206 + ] + }, + { + "id": "/en/far_cry_2008", + "directed_by": [ + "Uwe Boll" + ], + "initial_release_date": "2008-10-02", + "genre": [ + "Action Film", + "Science Fiction", + "Thriller", + "Adventure Film" + ], + "name": "Far Cry", + "film_vector": [ + -0.5072572231292725, + -0.21919971704483032, + -0.13140758872032166, + 0.24294593930244446, + 0.024822145700454712, + -0.18187715113162994, + -0.08855998516082764, + -0.16548621654510498, + -0.013246281072497368, + 0.01102360337972641 + ] + }, + { + "id": "/en/far_from_heaven", + "directed_by": [ + "Todd Haynes" + ], + "initial_release_date": "2002-09-01", + "genre": [ + "Romance Film", + "Melodrama", + "Drama" + ], + "name": "Far from Heaven", + "film_vector": [ + -0.2596115469932556, + 0.03966877609491348, + -0.30534252524375916, + 0.04618477821350098, + 0.3381308913230896, + -0.03135981038212776, + -0.13168422877788544, + 0.023840539157390594, + 0.05387154594063759, + -0.20847108960151672 + ] + }, + { + "id": "/en/farce_of_the_penguins", + "directed_by": [ + "Bob Saget" + ], + "genre": [ + "Parody", + "Mockumentary", + "Adventure Comedy", + "Comedy" + ], + "name": "Farce of the Penguins", + "film_vector": [ + 0.15173715353012085, + 0.05895140394568443, + -0.34788286685943604, + 0.12218078970909119, + -0.19439971446990967, + -0.14805546402931213, + 0.14032632112503052, + 0.1840365082025528, + -0.10341957211494446, + -0.1406245082616806 + ] + }, + { + "id": "/en/eagles_farewell_1_tour_live_from_melbourne", + "directed_by": [ + "Carol Dodds" + ], + "initial_release_date": "2005-06-14", + "genre": [ + "Music video" + ], + "name": "Eagles: Farewell 1 Tour-Live from Melbourne", + "film_vector": [ + 0.14858278632164001, + -0.022963522002100945, + -0.008525753393769264, + -0.037005312740802765, + 0.04603857547044754, + -0.18107056617736816, + -0.17154434323310852, + 0.019846728071570396, + 0.10979881882667542, + 0.24580144882202148 + ] + }, + { + "id": "/en/fat_albert", + "directed_by": [ + "Joel Zwick" + ], + "initial_release_date": "2004-12-12", + "genre": [ + "Family", + "Fantasy", + "Romance Film", + "Comedy" + ], + "name": "Fat Albert", + "film_vector": [ + -0.008626850321888924, + -0.00716240331530571, + -0.22359660267829895, + 0.22982953488826752, + 0.056814663112163544, + -0.16856834292411804, + -0.01399024948477745, + -0.11042578518390656, + 0.013019014149904251, + -0.3663467466831207 + ] + }, + { + "id": "/en/fat_pizza_the_movie", + "directed_by": [ + "Paul Fenech" + ], + "genre": [ + "Comedy" + ], + "name": "Fat Pizza", + "film_vector": [ + 0.16139014065265656, + 0.00583206070587039, + -0.2967946529388428, + 0.1122027337551117, + -0.02329595386981964, + -0.15668408572673798, + 0.2454962134361267, + -0.1327420175075531, + -0.009723675437271595, + -0.06226424500346184 + ] + }, + { + "id": "/en/fatwa_2006", + "directed_by": [ + "John Carter" + ], + "initial_release_date": "2006-03-24", + "genre": [ + "Thriller", + "Political thriller", + "Drama" + ], + "name": "Fatwa", + "film_vector": [ + -0.42461979389190674, + -0.08248336613178253, + -0.1239209994673729, + -0.19798609614372253, + 0.03699152544140816, + -0.06929774582386017, + 0.0769118070602417, + -0.05050761252641678, + -0.013121017254889011, + -0.11781871318817139 + ] + }, + { + "id": "/en/faust_love_of_the_damned", + "directed_by": [ + "Brian Yuzna" + ], + "initial_release_date": "2000-10-12", + "genre": [ + "Horror", + "Supernatural" + ], + "name": "Faust: Love of the Damned", + "film_vector": [ + -0.16171562671661377, + -0.2510390281677246, + 0.04423762857913971, + -0.11463598906993866, + 0.0064516011625528336, + 0.14094193279743195, + 0.132002592086792, + 0.22017702460289001, + 0.1767355501651764, + -0.28415632247924805 + ] + }, + { + "id": "/en/fay_grim", + "directed_by": [ + "Hal Hartley" + ], + "initial_release_date": "2006-09-11", + "genre": [ + "Thriller", + "Action Film", + "Political thriller", + "Indie film", + "Comedy Thriller", + "Comedy", + "Crime Fiction", + "Drama" + ], + "name": "Fay Grim", + "film_vector": [ + -0.5717809200286865, + -0.22676649689674377, + -0.35636770725250244, + -0.04221814125776291, + -0.06663356721401215, + -0.14345477521419525, + 0.051744163036346436, + 0.034464478492736816, + 0.05270709842443466, + -0.08833032846450806 + ] + }, + { + "id": "/en/fear_and_trembling_2003", + "directed_by": [ + "Alain Corneau" + ], + "genre": [ + "World cinema", + "Japanese Movies", + "Comedy", + "Drama" + ], + "name": "Fear and Trembling", + "film_vector": [ + -0.39710456132888794, + -0.03646358847618103, + -0.005579744465649128, + 0.1393040418624878, + -0.05484641715884209, + -0.10650325566530228, + 0.180993914604187, + 0.012322287075221539, + 0.2571066617965698, + -0.2666035294532776 + ] + }, + { + "id": "/en/fear_of_the_dark_2006", + "directed_by": [ + "Glen Baisley" + ], + "initial_release_date": "2001-10-06", + "genre": [ + "Horror", + "Mystery", + "Psychological thriller", + "Thriller", + "Drama" + ], + "name": "Fear of the Dark", + "film_vector": [ + -0.4781224727630615, + -0.3325536549091339, + -0.1144288182258606, + -0.05053465813398361, + -0.061462853103876114, + 0.03161292523145676, + 0.21538329124450684, + 0.2022022008895874, + 0.1437753587961197, + -0.09328798204660416 + ] + }, + { + "id": "/en/fear_x", + "directed_by": [ + "Nicolas Winding Refn" + ], + "initial_release_date": "2003-01-19", + "genre": [ + "Psychological thriller", + "Thriller" + ], + "name": "Fear X", + "film_vector": [ + -0.3532664179801941, + -0.42757126688957214, + -0.0646526962518692, + -0.02418547496199608, + 0.17004136741161346, + -0.028335843235254288, + 0.1570911556482315, + 0.03980283811688423, + 0.1228906512260437, + 0.04943238943815231 + ] + }, + { + "id": "/en/feardotcom", + "directed_by": [ + "William Malone" + ], + "initial_release_date": "2002-08-09", + "genre": [ + "Horror", + "Crime Fiction", + "Thriller", + "Mystery" + ], + "name": "FeardotCom", + "film_vector": [ + -0.49164149165153503, + -0.4550222158432007, + -0.1365865170955658, + -0.03513140603899956, + -0.06656660884618759, + 0.09211447089910507, + 0.16790801286697388, + 0.03895111009478569, + 0.14149171113967896, + -0.17573131620883942 + ] + }, + { + "id": "/en/fearless", + "directed_by": [ + "Ronny Yu" + ], + "initial_release_date": "2006-01-26", + "genre": [ + "Biographical film", + "Action Film", + "Sports", + "Drama" + ], + "name": "Fearless", + "film_vector": [ + -0.385113000869751, + -0.09164480119943619, + -0.1208161786198616, + 0.05145138502120972, + -0.08336955308914185, + -0.3118058145046234, + -0.15416088700294495, + -0.223650723695755, + 0.05429275333881378, + -0.13084861636161804 + ] + }, + { + "id": "/en/feast", + "directed_by": [ + "John Gulager" + ], + "initial_release_date": "2006-09-22", + "genre": [ + "Horror", + "Cult film", + "Monster movie", + "Horror comedy", + "Comedy" + ], + "name": "Feast", + "film_vector": [ + -0.23500686883926392, + -0.1868283748626709, + -0.24927440285682678, + 0.1024535521864891, + -0.008810842409729958, + -0.2415589839220047, + 0.19186200201511383, + 0.3132036030292511, + -0.0011343639343976974, + -0.10386157035827637 + ] + }, + { + "id": "/en/femme_fatale_2002", + "directed_by": [ + "Brian De Palma" + ], + "initial_release_date": "2002-04-30", + "genre": [ + "Thriller", + "Mystery", + "Crime Fiction", + "Erotic thriller" + ], + "name": "Femme Fatale", + "film_vector": [ + -0.6058768033981323, + -0.32262709736824036, + -0.3147977590560913, + -0.0985216423869133, + 0.05442332103848457, + 0.07633643597364426, + 0.062059275805950165, + -0.024991890415549278, + 0.1255382001399994, + -0.1355435848236084 + ] + }, + { + "id": "/en/festival_2005", + "directed_by": [ + "Annie Griffin" + ], + "initial_release_date": "2005-07-15", + "genre": [ + "Black comedy", + "Parody", + "Comedy" + ], + "name": "Festival", + "film_vector": [ + 0.07321193069219589, + 0.06204727292060852, + -0.31612348556518555, + -0.10503076016902924, + -0.2659189999103546, + -0.2157858908176422, + 0.3360788822174072, + 0.03469286859035492, + 0.08294269442558289, + -0.15357382595539093 + ] + }, + { + "id": "/en/festival_express", + "directed_by": [ + "Bob Smeaton" + ], + "genre": [ + "Documentary film", + "Concert film", + "History", + "Musical", + "Indie film", + "Rockumentary", + "Music" + ], + "name": "Festival Express", + "film_vector": [ + -0.2781173288822174, + 0.08476626873016357, + -0.19522710144519806, + 0.04530563950538635, + -0.14887043833732605, + -0.3971148729324341, + -0.1211869865655899, + 0.05549085885286331, + 0.28849008679389954, + 0.02285839430987835 + ] + }, + { + "id": "/en/festival_in_cannes", + "directed_by": [ + "Henry Jaglom" + ], + "initial_release_date": "2001-11-03", + "genre": [ + "Mockumentary", + "Comedy-drama", + "Comedy of manners", + "Ensemble Film", + "Comedy", + "Drama" + ], + "name": "Festival in Cannes", + "film_vector": [ + -0.08214948326349258, + 0.13547995686531067, + -0.29817840456962585, + -0.09524142742156982, + -0.07955305278301239, + -0.3231953978538513, + 0.1447419971227646, + 0.03519824147224426, + 0.0862717255949974, + -0.11609795689582825 + ] + }, + { + "id": "/en/fever_pitch_2005", + "directed_by": [ + "Bobby Farrelly", + "Peter Farrelly" + ], + "initial_release_date": "2005-04-06", + "genre": [ + "Romance Film", + "Sports", + "Comedy", + "Drama" + ], + "name": "Fever Pitch", + "film_vector": [ + -0.2929971218109131, + -0.04729574918746948, + -0.3357522487640381, + 0.039490293711423874, + 0.06484853476285934, + 0.02445652335882187, + -0.14304706454277039, + -0.19384072721004486, + 0.02552267350256443, + -0.017945315688848495 + ] + }, + { + "id": "/en/fida", + "directed_by": [ + "Ken Ghosh" + ], + "initial_release_date": "2004-08-20", + "genre": [ + "Romance Film", + "Adventure Film", + "Thriller", + "Drama" + ], + "name": "Fida", + "film_vector": [ + -0.5527008771896362, + 0.023090334609150887, + -0.19403398036956787, + 0.13816088438034058, + 0.12601229548454285, + -0.07381962984800339, + -0.06784430891275406, + -0.12646111845970154, + 0.09831435978412628, + -0.09161968529224396 + ] + }, + { + "id": "/en/fido_2006", + "directed_by": [ + "Andrew Currie" + ], + "initial_release_date": "2006-09-07", + "genre": [ + "Horror", + "Parody", + "Romance Film", + "Horror comedy", + "Comedy", + "Drama" + ], + "name": "Fido", + "film_vector": [ + -0.3805939555168152, + -0.054152339696884155, + -0.3449263572692871, + 0.16379866003990173, + -0.11841324716806412, + -0.12115681171417236, + 0.165359228849411, + 0.13915228843688965, + 0.1479330211877823, + -0.1466982066631317 + ] + }, + { + "id": "/en/fighter_in_the_wind", + "initial_release_date": "2004-08-06", + "name": "Fighter in the Wind", + "directed_by": [ + "Yang Yun-ho", + "Yang Yun-ho" + ], + "genre": [ + "Action/Adventure", + "Action Film", + "War film", + "Biographical film", + "Drama" + ], + "film_vector": [ + -0.4321855902671814, + -0.02858893945813179, + -0.03805193677544594, + 0.19495055079460144, + -0.01454635988920927, + -0.28470683097839355, + -0.28876209259033203, + -0.06664357334375381, + -0.12252174317836761, + -0.2050170600414276 + ] + }, + { + "id": "/en/filantropica", + "initial_release_date": "2002-03-15", + "name": "Filantropica", + "directed_by": [ + "Nae Caranfil" + ], + "genre": [ + "Comedy", + "Black comedy", + "Drama" + ], + "film_vector": [ + -0.21940745413303375, + -0.036806412041187286, + -0.327134907245636, + 0.05008181184530258, + -0.19353187084197998, + -0.13067428767681122, + 0.11003494262695312, + -0.012342475354671478, + 0.021999556571245193, + -0.29823875427246094 + ] + }, + { + "id": "/en/film_geek", + "initial_release_date": "2006-02-10", + "name": "Film Geek", + "directed_by": [ + "James Westby" + ], + "genre": [ + "Indie film", + "Workplace Comedy", + "Comedy" + ], + "film_vector": [ + -0.2832689881324768, + 0.07372040301561356, + -0.4499601721763611, + 0.14138200879096985, + -0.24935156106948853, + -0.2343524992465973, + 0.15338808298110962, + -0.14273004233837128, + 0.11823742091655731, + -0.05157157778739929 + ] + }, + { + "id": "/en/final_destination", + "initial_release_date": "2000-03-16", + "name": "Final Destination", + "directed_by": [ + "James Wong" + ], + "genre": [ + "Slasher", + "Teen film", + "Supernatural", + "Horror", + "Cult film", + "Thriller" + ], + "film_vector": [ + -0.4561137557029724, + -0.3694697916507721, + -0.21506467461585999, + 0.19383952021598816, + 0.06289569288492203, + -0.18250660598278046, + 0.03634931519627571, + 0.01917460560798645, + 0.13750296831130981, + 0.06638035178184509 + ] + }, + { + "id": "/en/final_destination_3", + "initial_release_date": "2006-02-09", + "name": "Final Destination 3", + "directed_by": [ + "James Wong" + ], + "genre": [ + "Slasher", + "Teen film", + "Horror", + "Thriller" + ], + "film_vector": [ + -0.3445751368999481, + -0.35458338260650635, + -0.14588117599487305, + 0.20088604092597961, + 0.19160878658294678, + -0.13165417313575745, + 0.028490280732512474, + -0.04977025091648102, + 0.15658143162727356, + 0.066404327750206 + ] + }, + { + "id": "/en/final_destination_2", + "initial_release_date": "2003-01-30", + "name": "Final Destination 2", + "directed_by": [ + "David R. Ellis" + ], + "genre": [ + "Slasher", + "Teen film", + "Supernatural", + "Horror", + "Cult film", + "Thriller" + ], + "film_vector": [ + -0.45367568731307983, + -0.3698350191116333, + -0.20096799731254578, + 0.21747593581676483, + 0.07135143131017685, + -0.18221694231033325, + 0.03298624977469444, + 0.029289381578564644, + 0.12164708971977234, + 0.07530155777931213 + ] + }, + { + "id": "/en/final_fantasy_vii_advent_children", + "initial_release_date": "2005-08-31", + "name": "Final Fantasy VII: Advent Children", + "directed_by": [ + "Tetsuya Nomura", + "Takeshi Nozue" + ], + "genre": [ + "Anime", + "Science Fiction", + "Animation", + "Action Film", + "Thriller" + ], + "film_vector": [ + -0.2557019591331482, + -0.10457693040370941, + 0.06576989591121674, + 0.39896026253700256, + -0.0790998786687851, + 0.06851263344287872, + -0.15904860198497772, + 0.02172137051820755, + 0.18096128106117249, + -0.09848262369632721 + ] + }, + { + "id": "/en/final_fantasy_the_spirits_within", + "initial_release_date": "2001-07-02", + "name": "Final Fantasy: The Spirits Within", + "directed_by": [ + "Hironobu Sakaguchi", + "Motonori Sakakibara" + ], + "genre": [ + "Science Fiction", + "Anime", + "Animation", + "Fantasy", + "Action Film", + "Adventure Film" + ], + "film_vector": [ + -0.26635441184043884, + -0.011563098058104515, + 0.19378037750720978, + 0.2918734550476074, + -0.13447362184524536, + 0.048435114324092865, + -0.040069352835416794, + 0.13114583492279053, + 0.19696292281150818, + -0.12200644612312317 + ] + }, + { + "id": "/en/final_stab", + "name": "Final Stab", + "directed_by": [ + "David DeCoteau" + ], + "genre": [ + "Horror", + "Slasher", + "Teen film" + ], + "film_vector": [ + -0.21242868900299072, + -0.3518180847167969, + -0.15733923017978668, + 0.12525524199008942, + 0.2880527377128601, + -0.11057758331298828, + 0.09829814732074738, + -0.07475977391004562, + 0.17633923888206482, + 0.03446398302912712 + ] + }, + { + "id": "/en/find_me_guilty", + "initial_release_date": "2006-02-16", + "name": "Find Me Guilty", + "directed_by": [ + "Sidney Lumet" + ], + "genre": [ + "Crime Fiction", + "Trial drama", + "Docudrama", + "Comedy-drama", + "Courtroom Comedy", + "Crime Comedy", + "Gangster Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.33133000135421753, + -0.15724320709705353, + -0.3269903063774109, + -0.18327432870864868, + -0.13692915439605713, + -0.14804883301258087, + 0.0752059668302536, + -0.01397911086678505, + -0.11218920350074768, + -0.16548578441143036 + ] + }, + { + "id": "/en/finders_fee", + "initial_release_date": "2001-06-16", + "name": "Finder's Fee", + "directed_by": [ + "Jeff Probst" + ], + "genre": [ + "Thriller", + "Psychological thriller", + "Indie film", + "Suspense", + "Drama" + ], + "film_vector": [ + -0.44886595010757446, + -0.3394784927368164, + -0.3410974442958832, + 0.05243734270334244, + 0.14115825295448303, + -0.20174705982208252, + -0.015185490250587463, + -0.08129601180553436, + 0.0747867003083229, + -0.07480740547180176 + ] + }, + { + "id": "/en/finding_nemo", + "initial_release_date": "2003-05-30", + "name": "Finding Nemo", + "directed_by": [ + "Andrew Stanton", + "Lee Unkrich" + ], + "genre": [ + "Animation", + "Adventure Film", + "Comedy", + "Family" + ], + "film_vector": [ + -0.11665394902229309, + 0.04247920960187912, + -0.1323336362838745, + 0.5257841348648071, + -0.1739290952682495, + -0.01880563050508499, + -0.06670808792114258, + -0.11242807656526566, + 0.09724514186382294, + -0.11909142136573792 + ] + }, + { + "id": "/en/finding_neverland", + "initial_release_date": "2004-09-04", + "name": "Finding Neverland", + "directed_by": [ + "Marc Forster" + ], + "genre": [ + "Costume drama", + "Historical period drama", + "Family", + "Biographical film", + "Drama" + ], + "film_vector": [ + -0.30782264471054077, + -0.0063843391835689545, + -0.21088802814483643, + 0.038129013031721115, + -0.11942115426063538, + -0.08559900522232056, + -0.19394713640213013, + 0.1362970620393753, + 0.11013343185186386, + -0.35169094800949097 + ] + }, + { + "id": "/en/fingerprints", + "name": "Fingerprints", + "directed_by": [ + "Harry Basil" + ], + "genre": [ + "Thriller", + "Horror", + "Mystery" + ], + "film_vector": [ + -0.37857741117477417, + -0.3898926377296448, + -0.0947594940662384, + -0.022609222680330276, + 0.13836786150932312, + 0.00823046825826168, + 0.15518926084041595, + -0.07306528836488724, + 0.08692796528339386, + -0.16363365948200226 + ] + }, + { + "id": "/en/firewall_2006", + "initial_release_date": "2006-02-02", + "name": "Firewall", + "directed_by": [ + "Richard Loncraine" + ], + "genre": [ + "Thriller", + "Action Film", + "Psychological thriller", + "Action/Adventure", + "Crime Thriller", + "Action Thriller" + ], + "film_vector": [ + -0.5278390049934387, + -0.28403520584106445, + -0.23686203360557556, + 0.09183751791715622, + 0.03723077103495598, + -0.09521738439798355, + -0.05754515156149864, + -0.14029493927955627, + -0.09036358445882797, + 0.01001659408211708 + ] + }, + { + "id": "/en/first_daughter", + "initial_release_date": "2004-09-24", + "name": "First Daughter", + "directed_by": [ + "Forest Whitaker" + ], + "genre": [ + "Romantic comedy", + "Teen film", + "Romance Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.36356115341186523, + 0.024191608652472496, + -0.5078942775726318, + 0.1972305178642273, + 0.2305685579776764, + -0.046472616493701935, + -0.1454821228981018, + -0.12409449368715286, + 0.1788707673549652, + -0.07857878506183624 + ] + }, + { + "id": "/en/first_descent", + "initial_release_date": "2005-12-02", + "name": "First Descent", + "directed_by": [ + "Kemp Curly", + "Kevin Harrison" + ], + "genre": [ + "Documentary film", + "Sports", + "Extreme Sports", + "Biographical film" + ], + "film_vector": [ + -0.11014461517333984, + -0.10313430428504944, + 0.13856878876686096, + 0.01139857992529869, + -0.01751200295984745, + -0.38944587111473083, + -0.20063728094100952, + -0.06713796406984329, + 0.05582674220204353, + -0.02892756089568138 + ] + }, + { + "id": "/en/fiza", + "initial_release_date": "2000-09-08", + "name": "Fiza", + "directed_by": [ + "Khalid Mohamed" + ], + "genre": [ + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.25458648800849915, + 0.1373075246810913, + -0.2103952169418335, + 0.053305234760046005, + 0.4213162064552307, + -0.01998155564069748, + -0.07812759280204773, + -0.10741081833839417, + 0.15352143347263336, + -0.19034089148044586 + ] + }, + { + "id": "/en/flags_of_our_fathers_2006", + "initial_release_date": "2006-10-20", + "name": "Flags of Our Fathers", + "directed_by": [ + "Clint Eastwood" + ], + "genre": [ + "War film", + "History", + "Action Film", + "Film adaptation", + "Historical drama", + "Drama" + ], + "film_vector": [ + -0.12260754406452179, + 0.023791730403900146, + -0.05023591220378876, + -0.005930120125412941, + -0.06257188320159912, + -0.34138602018356323, + -0.2800859808921814, + 0.13807249069213867, + -0.15939587354660034, + -0.22365902364253998 + ] + }, + { + "id": "/en/flight_from_death", + "initial_release_date": "2006-09-06", + "name": "Flight from Death", + "directed_by": [ + "Patrick Shen" + ], + "genre": [ + "Documentary film" + ], + "film_vector": [ + -0.02956319972872734, + -0.11967799067497253, + 0.12321321666240692, + -0.018946904689073563, + 0.12255211919546127, + -0.3802480697631836, + -0.10166020691394806, + 0.009441716596484184, + 0.14742949604988098, + -0.004378804005682468 + ] + }, + { + "id": "/en/flight_of_the_phoenix", + "initial_release_date": "2004-12-17", + "name": "Flight of the Phoenix", + "directed_by": [ + "John Moore" + ], + "genre": [ + "Airplanes and airports", + "Disaster Film", + "Action Film", + "Adventure Film", + "Action/Adventure", + "Film adaptation", + "Drama" + ], + "film_vector": [ + -0.27577391266822815, + -0.09390830248594284, + -0.17849673330783844, + 0.20598354935646057, + -0.05598694086074829, + -0.20665448904037476, + -0.20348528027534485, + 0.08111032843589783, + -0.14737913012504578, + -0.10113438963890076 + ] + }, + { + "id": "/en/flightplan", + "initial_release_date": "2005-09-22", + "name": "Flightplan", + "directed_by": [ + "Robert Schwentke" + ], + "genre": [ + "Thriller", + "Mystery", + "Drama" + ], + "film_vector": [ + -0.3400114178657532, + -0.2686457335948944, + -0.14772121608257294, + -0.10784123837947845, + 0.09289876371622086, + 0.06264763325452805, + -0.08767066895961761, + -0.11497752368450165, + -0.07534238696098328, + -0.0804959386587143 + ] + }, + { + "id": "/en/flock_of_dodos", + "name": "Flock of Dodos", + "directed_by": [ + "Randy Olson" + ], + "genre": [ + "Documentary film", + "History" + ], + "film_vector": [ + 0.12125779688358307, + -0.02654923126101494, + 0.11482376605272293, + 0.04020151495933533, + 0.08010274916887283, + -0.31001877784729004, + -0.08916492760181427, + 0.09268490970134735, + 0.07179215550422668, + -0.10982771217823029 + ] + }, + { + "id": "/en/fluffy_the_english_vampire_slayer", + "name": "Fluffy the English Vampire Slayer", + "directed_by": [ + "Henry Burrows" + ], + "genre": [ + "Horror comedy", + "Short Film", + "Fan film", + "Parody" + ], + "film_vector": [ + -0.00482364185154438, + -0.0583546981215477, + -0.1602640450000763, + 0.29965901374816895, + -0.008262861520051956, + -0.1482861191034317, + 0.1154211014509201, + 0.0818413645029068, + 0.1671350598335266, + -0.2804611623287201 + ] + }, + { + "id": "/en/flushed_away", + "initial_release_date": "2006-10-22", + "name": "Flushed Away", + "directed_by": [ + "David Bowers", + "Sam Fell" + ], + "genre": [ + "Animation", + "Family", + "Adventure Film", + "Children's/Family", + "Family-Oriented Adventure", + "Comedy" + ], + "film_vector": [ + -0.21761058270931244, + 0.01129523478448391, + -0.353049635887146, + 0.35374724864959717, + -0.09069740772247314, + -0.07058876752853394, + -0.11304306983947754, + -0.11647967994213104, + 0.14822828769683838, + -0.09118792414665222 + ] + }, + { + "id": "/en/fool_and_final", + "initial_release_date": "2007-06-01", + "name": "Fool & Final", + "directed_by": [ + "Ahmed Khan" + ], + "genre": [ + "Comedy", + "Action Film", + "Romance Film", + "Bollywood", + "World cinema" + ], + "film_vector": [ + -0.49920645356178284, + 0.29782891273498535, + -0.2730054557323456, + 0.1109103411436081, + -0.00892496109008789, + -0.19944193959236145, + 0.1371576339006424, + -0.1052321195602417, + -0.023923946544528008, + -0.07350974529981613 + ] + }, + { + "id": "/en/foolproof", + "initial_release_date": "2003-10-03", + "name": "Foolproof", + "directed_by": [ + "William Phillips" + ], + "genre": [ + "Action Film", + "Thriller", + "Crime Thriller", + "Action Thriller", + "Caper story", + "Crime Fiction", + "Comedy" + ], + "film_vector": [ + -0.539776086807251, + -0.27771246433258057, + -0.39115816354751587, + 0.035701870918273926, + -0.0940626859664917, + -0.17853133380413055, + -0.008871443569660187, + -0.01110159419476986, + -0.15745487809181213, + -0.024187609553337097 + ] + }, + { + "id": "/en/for_the_birds", + "initial_release_date": "2000-06-05", + "name": "For the Birds", + "directed_by": [ + "Ralph Eggleston" + ], + "genre": [ + "Short Film", + "Animation", + "Comedy", + "Family" + ], + "film_vector": [ + -0.09958842396736145, + 0.09289973229169846, + -0.2323666214942932, + 0.24903571605682373, + -0.24665306508541107, + -0.08742557466030121, + -0.013194985687732697, + -0.077616386115551, + 0.22246402502059937, + -0.0707625299692154 + ] + }, + { + "id": "/en/for_your_consideration_2006", + "initial_release_date": "2006-11-17", + "name": "For Your Consideration", + "directed_by": [ + "Christopher Guest" + ], + "genre": [ + "Mockumentary", + "Parody", + "Comedy" + ], + "film_vector": [ + 0.012381160631775856, + -0.009213495999574661, + -0.2968131899833679, + -0.03561754524707794, + -0.23617571592330933, + -0.2176508754491806, + 0.22145572304725647, + 0.06150727719068527, + -0.06516727060079575, + -0.03545433282852173 + ] + }, + { + "id": "/en/diev_mi_kas", + "initial_release_date": "2005-09-23", + "name": "Forest of the Gods", + "directed_by": [ + "Algimantas Puipa" + ], + "genre": [ + "War film", + "Drama" + ], + "film_vector": [ + -0.056878477334976196, + -0.0320664644241333, + 0.12817925214767456, + 0.073372483253479, + 0.18080873787403107, + -0.19732666015625, + -0.1644996702671051, + 0.15731148421764374, + -0.08974198997020721, + -0.2072741985321045 + ] + }, + { + "id": "/en/formula_17", + "initial_release_date": "2004-04-02", + "name": "Formula 17", + "directed_by": [ + "Chen Yin-jung" + ], + "genre": [ + "Romantic comedy", + "Romance Film", + "Comedy" + ], + "film_vector": [ + -0.27192744612693787, + 0.17806783318519592, + -0.4039677381515503, + 0.09385814517736435, + 0.3167547583580017, + -0.01431124284863472, + 0.00275434460490942, + -0.1699899137020111, + 0.012022426351904869, + -0.09300180524587631 + ] + }, + { + "id": "/en/forty_shades_of_blue", + "name": "Forty Shades of Blue", + "directed_by": [ + "Ira Sachs" + ], + "genre": [ + "Indie film", + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.2812492251396179, + -0.024385543540120125, + -0.370381236076355, + 0.020061958581209183, + 0.1578707993030548, + -0.13629959523677826, + -0.09132273495197296, + -0.10174152255058289, + 0.2099263072013855, + -0.14399263262748718 + ] + }, + { + "id": "/en/four_brothers_2005", + "initial_release_date": "2005-08-12", + "name": "Four Brothers", + "directed_by": [ + "John Singleton" + ], + "genre": [ + "Action Film", + "Crime Fiction", + "Thriller", + "Action/Adventure", + "Family Drama", + "Crime Drama", + "Drama" + ], + "film_vector": [ + -0.3973194360733032, + -0.15915708243846893, + -0.35111141204833984, + 0.0029952414333820343, + -0.09827859699726105, + -0.09114468097686768, + -0.12032772600650787, + -0.09279236197471619, + -0.16236081719398499, + -0.14678391814231873 + ] + }, + { + "id": "/en/frailty", + "initial_release_date": "2001-11-17", + "name": "Frailty", + "directed_by": [ + "Bill Paxton" + ], + "genre": [ + "Psychological thriller", + "Thriller", + "Crime Fiction", + "Drama" + ], + "film_vector": [ + -0.4385027289390564, + -0.2263055443763733, + -0.20077396929264069, + -0.14862209558486938, + -0.004399862140417099, + -0.023249704390764236, + 0.05858595669269562, + 0.05993446707725525, + 0.11175443977117538, + -0.18573154509067535 + ] + }, + { + "id": "/en/frankenfish", + "initial_release_date": "2004-10-09", + "name": "Frankenfish", + "directed_by": [ + "Mark A.Z. Dipp\u00e9" + ], + "genre": [ + "Action Film", + "Horror", + "Natural horror film", + "Monster", + "Science Fiction" + ], + "film_vector": [ + -0.34440112113952637, + -0.30038732290267944, + -0.02055392786860466, + 0.32325857877731323, + -0.023122217506170273, + -0.21182718873023987, + 0.08898082375526428, + 0.12677377462387085, + 0.10056334733963013, + -0.0704173594713211 + ] + }, + { + "id": "/en/franklin_and_grannys_secret", + "initial_release_date": "2006-12-20", + "name": "Franklin and the Turtle Lake Treasure", + "directed_by": [ + "Dominique Monf\u00e9ry" + ], + "genre": [ + "Family", + "Animation" + ], + "film_vector": [ + 0.19912642240524292, + -0.0283194687217474, + 0.09124168753623962, + 0.3938210606575012, + -0.07431359589099884, + 0.06449289619922638, + -0.15582118928432465, + -0.039485570043325424, + 0.05786675959825516, + -0.16282078623771667 + ] + }, + { + "id": "/en/franklin_and_the_green_knight", + "initial_release_date": "2000-10-17", + "name": "Franklin and the Green Knight", + "directed_by": [ + "John van Bruggen" + ], + "genre": [ + "Family", + "Animation" + ], + "film_vector": [ + 0.21754276752471924, + 0.01580831967294216, + 0.12218628823757172, + 0.3630938231945038, + -0.13821783661842346, + 0.12308657914400101, + -0.10677516460418701, + -0.05699190869927406, + -0.015837091952562332, + -0.15866777300834656 + ] + }, + { + "id": "/en/franklins_magic_christmas", + "initial_release_date": "2001-11-06", + "name": "Franklin's Magic Christmas", + "directed_by": [ + "John van Bruggen" + ], + "genre": [ + "Family", + "Animation" + ], + "film_vector": [ + 0.26230502128601074, + 0.10306859016418457, + -0.00842716358602047, + 0.3462420105934143, + -0.07917781174182892, + 0.1261349469423294, + -0.059115856885910034, + 0.028405554592609406, + 0.114626444876194, + -0.20871759951114655 + ] + }, + { + "id": "/en/freaky_friday_2003", + "initial_release_date": "2003-08-04", + "name": "Freaky Friday", + "directed_by": [ + "Mark Waters" + ], + "genre": [ + "Family", + "Fantasy", + "Comedy" + ], + "film_vector": [ + 0.004188987426459789, + -0.15855641663074493, + -0.3346690535545349, + 0.24776215851306915, + -0.11375805735588074, + 0.11528944969177246, + 0.13863523304462433, + -0.07126051932573318, + 0.17099601030349731, + -0.2004837542772293 + ] + }, + { + "id": "/en/freddy_vs_jason", + "initial_release_date": "2003-08-13", + "name": "Freddy vs. Jason", + "directed_by": [ + "Ronny Yu" + ], + "genre": [ + "Horror", + "Thriller", + "Slasher", + "Action Film", + "Crime Fiction" + ], + "film_vector": [ + -0.37262654304504395, + -0.3817424774169922, + -0.10465653240680695, + 0.15803591907024384, + -0.0508335679769516, + -0.04372222721576691, + 0.056561678647994995, + -0.00101509690284729, + 0.0053072962909936905, + -0.08808837085962296 + ] + }, + { + "id": "/en/free_jimmy", + "initial_release_date": "2006-04-21", + "name": "Free Jimmy", + "directed_by": [ + "Christopher Nielsen" + ], + "genre": [ + "Anime", + "Animation", + "Black comedy", + "Satire", + "Stoner film", + "Comedy" + ], + "film_vector": [ + -0.0931752547621727, + 0.06379885226488113, + -0.25560709834098816, + 0.10702868551015854, + -0.32981711626052856, + -0.14209231734275818, + 0.24007129669189453, + -0.11919261515140533, + 0.20430776476860046, + -0.13149812817573547 + ] + }, + { + "id": "/en/free_zone", + "initial_release_date": "2005-05-19", + "name": "Free Zone", + "directed_by": [ + "Amos Gitai" + ], + "genre": [ + "Comedy", + "Drama" + ], + "film_vector": [ + -0.04372047632932663, + 0.04278382286429405, + -0.3327636122703552, + -0.09781710058450699, + -0.1761322319507599, + -0.018044553697109222, + 0.17722272872924805, + -0.11448392271995544, + 0.15657925605773926, + -0.17485709488391876 + ] + }, + { + "id": "/en/freedomland", + "initial_release_date": "2006-02-17", + "name": "Freedomland", + "directed_by": [ + "Joe Roth" + ], + "genre": [ + "Mystery", + "Thriller", + "Crime Fiction", + "Film adaptation", + "Crime Thriller", + "Crime Drama", + "Drama" + ], + "film_vector": [ + -0.39140647649765015, + -0.23237119615077972, + -0.2034357488155365, + -0.1336912214756012, + 0.06399956345558167, + -0.19877375662326813, + -0.08041994273662567, + 0.013864257372915745, + -0.025800243020057678, + -0.25802502036094666 + ] + }, + { + "id": "/en/french_bean", + "initial_release_date": "2007-03-22", + "name": "Mr. Bean's Holiday", + "directed_by": [ + "Steve Bendelack" + ], + "genre": [ + "Family", + "Comedy", + "Road movie" + ], + "film_vector": [ + 0.2135729044675827, + 0.049604978412389755, + -0.26462826132774353, + 0.2524286210536957, + 0.023912841454148293, + -0.1028699278831482, + 0.09266830235719681, + -0.045006074011325836, + -0.02284335345029831, + -0.2386569380760193 + ] + }, + { + "id": "/en/frequency_2000", + "initial_release_date": "2000-04-28", + "name": "Frequency", + "directed_by": [ + "Gregory Hoblit" + ], + "genre": [ + "Thriller", + "Time travel", + "Science Fiction", + "Suspense", + "Fantasy", + "Crime Fiction", + "Family Drama", + "Drama" + ], + "film_vector": [ + -0.5988444089889526, + -0.13959600031375885, + -0.2476319670677185, + -0.11056166887283325, + -0.27424752712249756, + 0.13035297393798828, + -0.05968843400478363, + -0.005178365856409073, + 0.11479487270116806, + -0.12371007353067398 + ] + }, + { + "id": "/en/frida", + "initial_release_date": "2002-08-29", + "name": "Frida", + "directed_by": [ + "Julie Taymor" + ], + "genre": [ + "Biographical film", + "Romance Film", + "Political drama", + "Drama" + ], + "film_vector": [ + -0.414347767829895, + 0.14347726106643677, + -0.16620561480522156, + -0.014565780758857727, + 0.0970311239361763, + -0.18286362290382385, + -0.11355859041213989, + 0.014459345489740372, + 0.11533492058515549, + -0.24187886714935303 + ] + }, + { + "id": "/en/friday_after_next", + "initial_release_date": "2002-11-22", + "name": "Friday After Next", + "directed_by": [ + "Marcus Raboy" + ], + "genre": [ + "Buddy film", + "Comedy" + ], + "film_vector": [ + 0.023293744772672653, + -0.04928997531533241, + -0.36226725578308105, + 0.2041887491941452, + 0.09196335822343826, + -0.18216051161289215, + 0.1159820705652237, + -0.25265195965766907, + -0.08456388860940933, + -0.07258468866348267 + ] + }, + { + "id": "/en/friday_night_lights", + "initial_release_date": "2004-10-06", + "name": "Friday Night Lights", + "directed_by": [ + "Peter Berg" + ], + "genre": [ + "Action Film", + "Sports", + "Drama" + ], + "film_vector": [ + -0.11683454364538193, + -0.11173874884843826, + -0.18111270666122437, + 0.03972819074988365, + -0.09827370941638947, + -0.022892825305461884, + -0.12507683038711548, + -0.24341720342636108, + 0.01892741769552231, + -0.008704964071512222 + ] + }, + { + "id": "/en/friends_2001", + "initial_release_date": "2001-01-14", + "name": "Friends", + "directed_by": [ + "Siddique" + ], + "genre": [ + "Romance Film", + "Comedy", + "Drama", + "Tamil cinema", + "World cinema" + ], + "film_vector": [ + -0.5529738664627075, + 0.39549171924591064, + -0.2074611335992813, + 0.08227235078811646, + 0.0016939034685492516, + -0.04990985617041588, + 0.11241784691810608, + -0.1566508412361145, + 0.08825838565826416, + -0.04973769187927246 + ] + }, + { + "id": "/en/friends_with_money", + "initial_release_date": "2006-04-07", + "name": "Friends with Money", + "directed_by": [ + "Nicole Holofcener" + ], + "genre": [ + "Romance Film", + "Indie film", + "Comedy-drama", + "Comedy of manners", + "Ensemble Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.2613990902900696, + 0.031753059476614, + -0.6057716608047485, + 0.054647475481033325, + 0.014059105888009071, + -0.21168096363544464, + -0.04952584207057953, + 0.017594903707504272, + -0.001061285613104701, + -0.04824022203683853 + ] + }, + { + "id": "/en/fro_the_movie", + "name": "FRO - The Movie", + "directed_by": [ + "Brad Gashler", + "Michael J. Brooks" + ], + "genre": [ + "Comedy-drama" + ], + "film_vector": [ + -0.015614069998264313, + 0.040188852697610855, + -0.27612432837486267, + 0.07890493422746658, + 0.11521752178668976, + -0.10155986249446869, + 0.050662506371736526, + -0.060979247093200684, + 0.08972565829753876, + -0.17534011602401733 + ] + }, + { + "id": "/en/from_hell_2001", + "initial_release_date": "2001-09-08", + "name": "From Hell", + "directed_by": [ + "Allen Hughes", + "Albert Hughes" + ], + "genre": [ + "Thriller", + "Mystery", + "Biographical film", + "Crime Fiction", + "Slasher", + "Film adaptation", + "Horror", + "Drama" + ], + "film_vector": [ + -0.5456500053405762, + -0.3236906826496124, + -0.23636068403720856, + -0.02137685753405094, + -0.06063925102353096, + -0.17989268898963928, + 0.08542037010192871, + 0.14390794932842255, + 0.026268327608704567, + -0.11461590230464935 + ] + }, + { + "id": "/en/from_janet_to_damita_jo_the_videos", + "initial_release_date": "2004-09-07", + "name": "From Janet to Damita Jo: The Videos", + "directed_by": [ + "Jonathan Dayton", + "Mark Romanek", + "Paul Hunter" + ], + "genre": [ + "Music video" + ], + "film_vector": [ + -0.005403604358434677, + 0.16768445074558258, + -0.024717465043067932, + -0.0165405236184597, + 0.16792628169059753, + -0.1291097104549408, + -0.04266996681690216, + 0.008608641102910042, + 0.2424229085445404, + 0.218799889087677 + ] + }, + { + "id": "/en/from_justin_to_kelly", + "initial_release_date": "2003-06-20", + "name": "From Justin to Kelly", + "directed_by": [ + "Robert Iscove" + ], + "genre": [ + "Musical", + "Romantic comedy", + "Teen film", + "Romance Film", + "Beach Film", + "Musical comedy", + "Comedy" + ], + "film_vector": [ + -0.2607053220272064, + 0.02049936167895794, + -0.5805530548095703, + 0.1815415471792221, + 0.036626607179641724, + -0.1370704174041748, + -0.17583423852920532, + 0.029020268470048904, + 0.10872067511081696, + 0.03138516843318939 + ] + }, + { + "id": "/en/frostbite_2005", + "name": "Frostbite", + "directed_by": [ + "Jonathan Schwartz" + ], + "genre": [ + "Sports", + "Comedy" + ], + "film_vector": [ + 0.06375211477279663, + 0.05679652467370033, + -0.26055967807769775, + 0.03657232224941254, + -0.33635056018829346, + -0.05702836066484451, + 0.16141793131828308, + -0.1804267317056656, + 0.07551136612892151, + -0.005421638488769531 + ] + }, + { + "id": "/en/fubar_2002", + "initial_release_date": "2002-01-01", + "name": "FUBAR", + "directed_by": [ + "Michael Dowse" + ], + "genre": [ + "Mockumentary", + "Indie film", + "Buddy film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.1964288353919983, + -0.010428596287965775, + -0.45794641971588135, + 0.09671810269355774, + -0.11996448040008545, + -0.3595004081726074, + 0.08766850084066391, + -0.07058877497911453, + 0.0608271062374115, + -0.022591514512896538 + ] + }, + { + "id": "/en/fuck_2005", + "initial_release_date": "2005-11-07", + "name": "Fuck", + "directed_by": [ + "Steve Anderson" + ], + "genre": [ + "Documentary film", + "Indie film", + "Political cinema" + ], + "film_vector": [ + -0.29224807024002075, + 0.10041824728250504, + -0.10427719354629517, + -0.061399176716804504, + -0.19488222897052765, + -0.3907207250595093, + 0.012834398075938225, + -0.030302129685878754, + 0.2763945460319519, + 0.014375659637153149 + ] + }, + { + "id": "/en/fuckland", + "initial_release_date": "2000-09-21", + "name": "Fuckland", + "directed_by": [ + "Jos\u00e9 Luis M\u00e1rques" + ], + "genre": [ + "Indie film", + "Dogme 95", + "Comedy-drama", + "Satire", + "Comedy of manners", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.10699979960918427, + 0.020989859476685524, + -0.3298908472061157, + -0.020415792241692543, + -0.10323460400104523, + -0.31027770042419434, + 0.12744088470935822, + 0.05577792227268219, + 0.17037303745746613, + -0.17769840359687805 + ] + }, + { + "id": "/en/full_court_miracle", + "initial_release_date": "2003-11-21", + "name": "Full-Court Miracle", + "directed_by": [ + "Stuart Gillard" + ], + "genre": [ + "Family", + "Drama" + ], + "film_vector": [ + 0.2704220414161682, + -0.03490370512008667, + -0.1909981071949005, + -0.16442009806632996, + 0.02136419713497162, + 0.24838519096374512, + -0.09797947853803635, + -0.13448674976825714, + -0.07564795017242432, + 0.03907451778650284 + ] + }, + { + "id": "/en/full_disclosure_2001", + "initial_release_date": "2001-05-15", + "name": "Full Disclosure", + "directed_by": [ + "John Bradshaw" + ], + "genre": [ + "Thriller", + "Action/Adventure", + "Action Film", + "Political thriller" + ], + "film_vector": [ + -0.54013991355896, + -0.31043073534965515, + -0.24300506711006165, + -0.009907148778438568, + 0.06446672976016998, + -0.14763274788856506, + -0.06839986145496368, + -0.1138710230588913, + 0.04154301434755325, + -0.025516077876091003 + ] + }, + { + "id": "/en/full_frontal", + "initial_release_date": "2002-08-02", + "name": "Full Frontal", + "directed_by": [ + "Steven Soderbergh" + ], + "genre": [ + "Romantic comedy", + "Indie film", + "Romance Film", + "Comedy-drama", + "Ensemble Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.3082296550273895, + 0.06476065516471863, + -0.614551305770874, + 0.08402539044618607, + -0.029438043013215065, + -0.21673281490802765, + -0.0041963327676057816, + 0.06629722565412521, + 0.036678846925497055, + 0.010183908976614475 + ] + }, + { + "id": "/wikipedia/ja/$5287$5834$7248_$92FC$306E$932C$91D1$8853$5E2B_$30B7$30E3$30F3$30D0$30E9$3092$5F81$304F$8005", + "initial_release_date": "2005-07-23", + "name": "Fullmetal Alchemist the Movie: Conqueror of Shamballa", + "directed_by": [ + "Seiji Mizushima" + ], + "genre": [ + "Anime", + "Fantasy", + "Action Film", + "Animation", + "Adventure Film", + "Drama" + ], + "film_vector": [ + -0.33875495195388794, + 0.031119108200073242, + 0.010634386911988258, + 0.29837822914123535, + -0.03499918431043625, + -0.10050933063030243, + -0.13847249746322632, + 0.11795014142990112, + -0.02123268134891987, + -0.14254480600357056 + ] + }, + { + "id": "/en/fulltime_killer", + "initial_release_date": "2001-08-03", + "name": "Fulltime Killer", + "directed_by": [ + "Johnnie To", + "Wai Ka-fai" + ], + "genre": [ + "Action Film", + "Thriller", + "Crime Fiction", + "Martial Arts Film", + "Action Thriller", + "Drama" + ], + "film_vector": [ + -0.648762583732605, + -0.24821293354034424, + -0.21131011843681335, + 0.028963666409254074, + -0.0189075767993927, + -0.16880516707897186, + 0.018742317333817482, + -0.1554877758026123, + -0.05955389887094498, + -0.0238320492208004 + ] + }, + { + "id": "/en/fun_with_dick_and_jane_2005", + "initial_release_date": "2005-12-21", + "name": "Fun with Dick and Jane", + "directed_by": [ + "Dean Parisot" + ], + "genre": [ + "Crime Fiction", + "Comedy" + ], + "film_vector": [ + -0.12752830982208252, + -0.18192435801029205, + -0.3560410737991333, + -0.04835476726293564, + -0.10918371379375458, + 0.036109160631895065, + 0.13802656531333923, + -0.238010972738266, + 0.02408551797270775, + -0.3401584029197693 + ] + }, + { + "id": "/en/funny_ha_ha", + "name": "Funny Ha Ha", + "directed_by": [ + "Andrew Bujalski" + ], + "genre": [ + "Indie film", + "Romantic comedy", + "Romance Film", + "Mumblecore", + "Comedy-drama", + "Comedy of manners", + "Comedy" + ], + "film_vector": [ + -0.3327677845954895, + 0.11501811444759369, + -0.6342748999595642, + 0.06136932969093323, + -0.04927507042884827, + -0.2494276463985443, + 0.08698149770498276, + 0.13024801015853882, + -0.005910045467317104, + -0.06320381909608841 + ] + }, + { + "id": "/en/g-sale", + "initial_release_date": "2005-11-15", + "name": "G-Sale", + "directed_by": [ + "Randy Nargi" + ], + "genre": [ + "Mockumentary", + "Comedy of manners", + "Comedy" + ], + "film_vector": [ + 0.1484440118074417, + 0.035269204527139664, + -0.35148152709007263, + -0.044070128351449966, + -0.08367615193128586, + -0.19217592477798462, + 0.2933868169784546, + 0.029579324647784233, + -0.10294089466333389, + -0.1513691544532776 + ] + }, + { + "id": "/en/gabrielle_2006", + "initial_release_date": "2005-09-05", + "name": "Gabrielle", + "directed_by": [ + "Patrice Ch\u00e9reau" + ], + "genre": [ + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.22710943222045898, + 0.05229298397898674, + -0.30277931690216064, + 0.024944132193922997, + 0.4275585412979126, + 0.000850403681397438, + -0.10917378962039948, + -0.12347246706485748, + 0.1727224886417389, + -0.13931792974472046 + ] + }, + { + "id": "/en/gagamboy", + "initial_release_date": "2004-01-01", + "name": "Gagamboy", + "directed_by": [ + "Erik Matti" + ], + "genre": [ + "Action Film", + "Science Fiction", + "Comedy", + "Fantasy" + ], + "film_vector": [ + -0.3856126368045807, + 0.05191212147474289, + -0.06173503398895264, + 0.23734763264656067, + -0.05272766575217247, + -0.019593076780438423, + 0.037777505815029144, + -0.06437379121780396, + 0.07582884281873703, + -0.21563510596752167 + ] + }, + { + "id": "/en/gallipoli_2005", + "initial_release_date": "2005-03-18", + "name": "Gallipoli", + "directed_by": [ + "Tolga \u00d6rnek" + ], + "genre": [ + "Documentary film", + "War film" + ], + "film_vector": [ + -0.011225524358451366, + 0.06283998489379883, + 0.14518862962722778, + -0.06297712028026581, + 0.04960561543703079, + -0.4362249970436096, + -0.1483861356973648, + 0.030794735997915268, + 0.07142698019742966, + -0.22162607312202454 + ] + }, + { + "id": "/en/game_6_2006", + "initial_release_date": "2006-03-10", + "name": "Game 6", + "directed_by": [ + "Michael Hoffman" + ], + "genre": [ + "Indie film", + "Sports", + "Comedy-drama", + "Drama" + ], + "film_vector": [ + -0.24836334586143494, + -0.030126098543405533, + -0.2881481647491455, + -0.06238889694213867, + -0.2125558853149414, + -0.09661027044057846, + -0.11503007262945175, + -0.19621542096138, + 0.0808180719614029, + 0.016629032790660858 + ] + }, + { + "id": "/en/game_over_2003", + "initial_release_date": "2003-06-23", + "name": "Maximum Surge", + "directed_by": [ + "Jason Bourque" + ], + "genre": [ + "Science Fiction" + ], + "film_vector": [ + -0.15886816382408142, + -0.15598037838935852, + 0.1391109824180603, + -0.04049864411354065, + -0.10877189040184021, + 0.08579403907060623, + -0.06134124472737312, + -0.030985437333583832, + -0.030340272933244705, + 0.03156305477023125 + ] + }, + { + "id": "/en/gamma_squad", + "initial_release_date": "2004-06-14", + "name": "Expendable", + "directed_by": [ + "Nathaniel Barker", + "Eliot Lash" + ], + "genre": [ + "Indie film", + "Short Film", + "War film" + ], + "film_vector": [ + -0.3474313020706177, + -0.013293752446770668, + -0.10198215395212173, + 0.04823298007249832, + -0.07805225253105164, + -0.4769251346588135, + -0.0551113598048687, + -0.15868133306503296, + 0.1276041716337204, + -0.11559636890888214 + ] + }, + { + "id": "/en/gangotri_2003", + "initial_release_date": "2003-03-28", + "name": "Gangotri", + "directed_by": [ + "Kovelamudi Raghavendra Rao" + ], + "genre": [ + "Romance Film", + "Drama", + "Tollywood", + "World cinema" + ], + "film_vector": [ + -0.5308985710144043, + 0.3513292074203491, + -0.10334905236959457, + 0.009992983192205429, + 0.15410469472408295, + -0.06522111594676971, + 0.16171231865882874, + -0.09625957906246185, + 0.03189146891236305, + -0.08206699788570404 + ] + }, + { + "id": "/en/gangs_of_new_york", + "initial_release_date": "2002-12-09", + "name": "Gangs of New York", + "directed_by": [ + "Martin Scorsese" + ], + "genre": [ + "Crime Fiction", + "Historical drama", + "Drama" + ], + "film_vector": [ + -0.2110849916934967, + -0.15487687289714813, + -0.14905595779418945, + -0.3318466246128082, + -0.15753009915351868, + -0.029435135424137115, + -0.0748559981584549, + -0.12027257680892944, + 0.019117357209324837, + -0.23945412039756775 + ] + }, + { + "id": "/en/gangster_2006", + "initial_release_date": "2006-04-28", + "name": "Gangster", + "directed_by": [ + "Anurag Basu" + ], + "genre": [ + "Thriller", + "Romance Film", + "Mystery", + "World cinema", + "Crime Fiction", + "Bollywood", + "Drama" + ], + "film_vector": [ + -0.751579761505127, + 0.022481868043541908, + -0.22860673069953918, + -0.05661364644765854, + -0.08820676803588867, + -0.11553634703159332, + 0.11990669369697571, + -0.13162021338939667, + -0.037576355040073395, + -0.07950180768966675 + ] + }, + { + "id": "/en/gangster_no_1", + "initial_release_date": "2000-06-09", + "name": "Gangster No. 1", + "directed_by": [ + "Paul McGuigan" + ], + "genre": [ + "Thriller", + "Crime Fiction", + "Historical period drama", + "Action Film", + "Crime Thriller", + "Action/Adventure", + "Gangster Film", + "Drama" + ], + "film_vector": [ + -0.4005897641181946, + -0.24361959099769592, + -0.2799335718154907, + -0.12641209363937378, + 0.0252365842461586, + -0.2193284034729004, + -0.04323035478591919, + -0.006691145710647106, + -0.2284921109676361, + -0.11704769730567932 + ] + }, + { + "id": "/en/garam_masala_2005", + "initial_release_date": "2005-11-02", + "name": "Garam Masala", + "directed_by": [ + "Priyadarshan" + ], + "genre": [ + "Comedy" + ], + "film_vector": [ + -0.0474359393119812, + 0.25777778029441833, + -0.1486670821905136, + 0.07825174182653427, + 0.11158616840839386, + -0.11232313513755798, + 0.39521464705467224, + -0.03593166917562485, + -0.09588883072137833, + -0.12274253368377686 + ] + }, + { + "id": "/en/garcon_stupide", + "initial_release_date": "2004-03-10", + "name": "Gar\u00e7on stupide", + "directed_by": [ + "Lionel Baier" + ], + "genre": [ + "LGBT", + "World cinema", + "Gay", + "Gay Interest", + "Gay Themed", + "Coming of age", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.24877962470054626, + 0.20317324995994568, + -0.28334710001945496, + -0.032639652490615845, + -0.2044462263584137, + -0.04994972422719002, + -0.01745770126581192, + 0.040922652930021286, + 0.23168642818927765, + -0.12080194056034088 + ] + }, + { + "id": "/en/garden_state", + "initial_release_date": "2004-01-16", + "name": "Garden State", + "directed_by": [ + "Zach Braff" + ], + "genre": [ + "Romantic comedy", + "Coming of age", + "Romance Film", + "Comedy-drama", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.2557869255542755, + 0.050150398164987564, + -0.6161172986030579, + 0.05017058551311493, + 0.05089893192052841, + -0.10145464539527893, + -0.10284829139709473, + 0.03197351098060608, + 0.09440898895263672, + -0.08642657101154327 + ] + }, + { + "id": "/en/garfield_2004", + "initial_release_date": "2004-06-06", + "name": "Garfield: The Movie", + "directed_by": [ + "Peter Hewitt" + ], + "genre": [ + "Slapstick", + "Animation", + "Family", + "Comedy" + ], + "film_vector": [ + 0.15640774369239807, + 0.07637374103069305, + -0.16418865323066711, + 0.3194165825843811, + -0.20914550125598907, + -0.10859523713588715, + 0.14670415222644806, + -0.06662185490131378, + -0.014063017442822456, + -0.2859921157360077 + ] + }, + { + "id": "/en/garfield_a_tail_of_two_kitties", + "initial_release_date": "2006-06-15", + "name": "Garfield: A Tail of Two Kitties", + "directed_by": [ + "Tim Hill" + ], + "genre": [ + "Family", + "Animal Picture", + "Children's/Family", + "Family-Oriented Adventure", + "Comedy" + ], + "film_vector": [ + 0.05601045489311218, + 0.031952254474163055, + -0.1652015894651413, + 0.36508792638778687, + -0.2967807352542877, + 0.06007625162601471, + 0.005401669070124626, + -0.04953743517398834, + 0.0839478000998497, + -0.24090343713760376 + ] + }, + { + "id": "/en/gene-x", + "name": "Gene-X", + "directed_by": [ + "Martin Simpson" + ], + "genre": [ + "Thriller", + "Romance Film" + ], + "film_vector": [ + -0.2152908742427826, + -0.1866357922554016, + -0.21286897361278534, + 0.1512959599494934, + 0.43648427724838257, + -0.09451505541801453, + -0.05829539895057678, + -0.15703298151493073, + 0.09894591569900513, + -0.05052485316991806 + ] + }, + { + "id": "/en/george_of_the_jungle_2", + "initial_release_date": "2003-08-18", + "name": "George of the Jungle 2", + "directed_by": [ + "David Grossman" + ], + "genre": [ + "Parody", + "Slapstick", + "Family", + "Jungle Film", + "Comedy" + ], + "film_vector": [ + 0.07687167078256607, + 0.08112011104822159, + -0.2238343060016632, + 0.263701468706131, + -0.061040326952934265, + -0.2760618329048157, + 0.16161182522773743, + 0.05180410295724869, + -0.1562255322933197, + -0.15552487969398499 + ] + }, + { + "id": "/en/george_washington_2000", + "initial_release_date": "2000-09-29", + "name": "George Washington", + "directed_by": [ + "David Gordon Green" + ], + "genre": [ + "Coming of age", + "Indie film", + "Drama" + ], + "film_vector": [ + -0.12401419132947922, + -0.054373692721128464, + -0.17574118077754974, + -0.018219247460365295, + 0.08326909691095352, + -0.2946118414402008, + -0.26155516505241394, + -0.13148313760757446, + 0.15046215057373047, + -0.2629260718822479 + ] + }, + { + "id": "/en/georgia_rule", + "initial_release_date": "2007-05-10", + "name": "Georgia Rule", + "directed_by": [ + "Garry Marshall" + ], + "genre": [ + "Comedy-drama", + "Romance Film", + "Melodrama", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.09621138870716095, + 0.0059010544791817665, + -0.38718414306640625, + -0.04321694374084473, + 0.17199167609214783, + -0.15538936853408813, + -0.01234409585595131, + -0.09354118257761002, + -0.020668234676122665, + -0.2499152272939682 + ] + }, + { + "id": "/en/gerry", + "initial_release_date": "2003-02-14", + "name": "Gerry", + "directed_by": [ + "Gus Van Sant" + ], + "genre": [ + "Indie film", + "Adventure Film", + "Mystery", + "Avant-garde", + "Experimental film", + "Buddy film", + "Drama" + ], + "film_vector": [ + -0.31223785877227783, + -0.009041406214237213, + -0.28217875957489014, + 0.15141375362873077, + -0.13701899349689484, + -0.3307408392429352, + -0.022773118689656258, + -0.12065882235765457, + 0.1684611439704895, + -0.18243460357189178 + ] + }, + { + "id": "/en/get_a_clue", + "initial_release_date": "2002-06-28", + "name": "Get a Clue", + "directed_by": [ + "Maggie Greenwald Mansfield" + ], + "genre": [ + "Mystery", + "Comedy" + ], + "film_vector": [ + 0.05239913985133171, + -0.12346917390823364, + -0.4032597541809082, + 0.06730302423238754, + -0.009128733538091183, + -0.1270398199558258, + 0.30223706364631653, + -0.048648275434970856, + -0.050225310027599335, + -0.19787874817848206 + ] + }, + { + "id": "/en/get_over_it", + "initial_release_date": "2001-03-09", + "name": "Get Over It", + "directed_by": [ + "Tommy O'Haver" + ], + "genre": [ + "Musical", + "Romantic comedy", + "Teen film", + "Romance Film", + "School story", + "Farce", + "Gay", + "Gay Interest", + "Gay Themed", + "Sex comedy", + "Musical comedy", + "Comedy" + ], + "film_vector": [ + -0.2016575038433075, + 0.08367019146680832, + -0.6620504856109619, + 0.05589570477604866, + -0.10334998369216919, + -0.09433425962924957, + -0.12765680253505707, + 0.21910429000854492, + 0.011217801831662655, + 0.03644181787967682 + ] + }, + { + "id": "/en/get_rich_or_die_tryin", + "initial_release_date": "2005-11-09", + "name": "Get Rich or Die Tryin'", + "directed_by": [ + "Jim Sheridan" + ], + "genre": [ + "Coming of age", + "Crime Fiction", + "Hip hop film", + "Action Film", + "Biographical film", + "Musical Drama", + "Drama" + ], + "film_vector": [ + -0.44856640696525574, + -0.05250909924507141, + -0.41825413703918457, + 0.05213332921266556, + -0.12819795310497284, + -0.22730614244937897, + -0.14298099279403687, + -0.16611972451210022, + 0.11844448745250702, + -0.04301302507519722 + ] + }, + { + "id": "/en/get_up", + "name": "Get Up!", + "directed_by": [ + "Kazuyuki Izutsu" + ], + "genre": [ + "Musical", + "Action Film", + "Japanese Movies", + "Musical Drama", + "Musical comedy", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.2552468180656433, + 0.1263038069009781, + -0.3586401045322418, + 0.20869669318199158, + -0.052288927137851715, + -0.08204960078001022, + -0.07153169065713882, + 0.11656048893928528, + 0.05798501521348953, + -0.007315383292734623 + ] + }, + { + "id": "/en/getting_my_brother_laid", + "name": "Getting My Brother Laid", + "directed_by": [ + "Sven Taddicken" + ], + "genre": [ + "Romantic comedy", + "Romance Film", + "Comedy", + "Drama" + ], + "film_vector": [ + -0.2512247562408447, + 0.030655916780233383, + -0.5017508864402771, + 0.04904524236917496, + 0.03665825352072716, + -0.015016087330877781, + -0.027188871055841446, + -0.14664989709854126, + 0.06400112807750702, + -0.10933440178632736 + ] + }, + { + "id": "/en/getting_there", + "initial_release_date": "2002-06-11", + "name": "Getting There: Sweet 16 and Licensed to Drive", + "directed_by": [ + "Steve Purcell" + ], + "genre": [ + "Family", + "Teen film", + "Comedy" + ], + "film_vector": [ + -0.12504953145980835, + -0.03069133684039116, + -0.45926275849342346, + 0.11022044718265533, + -0.04216713458299637, + -0.1471240222454071, + -0.056181978434324265, + -0.3041042685508728, + 0.26209867000579834, + 0.049482665956020355 + ] + }, + { + "id": "/en/ghajini", + "initial_release_date": "2005-09-29", + "name": "Ghajini", + "directed_by": [ + "A.R. Murugadoss" + ], + "genre": [ + "Thriller", + "Action Film", + "Mystery", + "Romance Film", + "Drama" + ], + "film_vector": [ + -0.5741335153579712, + 0.07402914017438889, + -0.17470520734786987, + 0.07291582226753235, + 0.2370920181274414, + -0.08329162001609802, + 0.12695807218551636, + -0.10194068402051926, + -0.04313015937805176, + -0.017474479973316193 + ] + }, + { + "id": "/en/gharshana", + "initial_release_date": "2004-07-30", + "name": "Gharshana", + "directed_by": [ + "Gautham Menon" + ], + "genre": [ + "Mystery", + "Crime Fiction", + "Romance Film", + "Action Film", + "Tollywood", + "World cinema", + "Drama" + ], + "film_vector": [ + -0.7071300745010376, + 0.2169446051120758, + -0.06110094487667084, + 0.01708238571882248, + 0.024330953136086464, + -0.03887348622083664, + 0.13462358713150024, + -0.11121346056461334, + -0.06728117167949677, + -0.14214010536670685 + ] + }, + { + "id": "/en/ghilli", + "initial_release_date": "2004-04-17", + "name": "Ghilli", + "directed_by": [ + "Dharani" + ], + "genre": [ + "Sports", + "Action Film", + "Romance Film", + "Comedy" + ], + "film_vector": [ + -0.4605671167373657, + 0.1505115032196045, + -0.22611811757087708, + 0.15978054702281952, + 0.006566525436937809, + -0.11621477454900742, + -0.04934527352452278, + -0.2570064663887024, + 0.015141604468226433, + -0.074055515229702 + ] + }, + { + "id": "/en/ghost_game_2006", + "initial_release_date": "2005-09-01", + "name": "Ghost Game", + "directed_by": [ + "Joe Knee" + ], + "genre": [ + "Horror comedy" + ], + "film_vector": [ + -0.0414227731525898, + -0.3171876072883606, + -0.1479487419128418, + 0.19996818900108337, + 0.03800912946462631, + -0.059950441122055054, + 0.37837180495262146, + 0.028098242357373238, + 0.13351896405220032, + -0.11499213427305222 + ] + }, + { + "id": "/en/ghost_house", + "initial_release_date": "2004-09-17", + "name": "Ghost House", + "directed_by": [ + "Kim Sang-jin" + ], + "genre": [ + "Horror", + "Horror comedy", + "Comedy", + "East Asian cinema", + "World cinema" + ], + "film_vector": [ + -0.429352343082428, + -0.06801949441432953, + -0.12308166921138763, + 0.15279917418956757, + -0.11863172799348831, + -0.1547280102968216, + 0.3292912244796753, + 0.1066439226269722, + 0.2680853307247162, + -0.21329441666603088 + ] + }, + { + "id": "/en/ghost_in_the_shell_2_innocence", + "initial_release_date": "2004-03-06", + "name": "Ghost in the Shell 2: Innocence", + "directed_by": [ + "Mamoru Oshii" + ], + "genre": [ + "Science Fiction", + "Anime", + "Action Film", + "Animation", + "Thriller", + "Drama" + ], + "film_vector": [ + -0.3565676212310791, + -0.2740764021873474, + -0.015410549938678741, + 0.2731671929359436, + 0.02106073871254921, + 0.015141235664486885, + 0.028297409415245056, + -0.012924056500196457, + 0.135958731174469, + 0.007266571745276451 + ] + }, + { + "id": "/en/s_a_c_solid_state_society", + "initial_release_date": "2006-09-01", + "name": "Ghost in the Shell: Solid State Society", + "directed_by": [ + "Kenji Kamiyama" + ], + "genre": [ + "Anime", + "Science Fiction", + "Action Film", + "Animation", + "Thriller", + "Adventure Film", + "Fantasy" + ], + "film_vector": [ + -0.3677283525466919, + -0.22017502784729004, + -0.009933451190590858, + 0.2616170048713684, + -0.14594896137714386, + 0.01908930577337742, + 0.006616007536649704, + -0.024326462298631668, + 0.12047094106674194, + -0.03278760239481926 + ] + }, + { + "id": "/en/ghost_lake", + "initial_release_date": "2005-05-17", + "name": "Ghost Lake", + "directed_by": [ + "Jay Woelfel" + ], + "genre": [ + "Horror", + "Zombie Film" + ], + "film_vector": [ + -0.08960967510938644, + -0.35444262623786926, + -0.028002604842185974, + 0.20975810289382935, + 0.2506555914878845, + -0.25908273458480835, + 0.1432565450668335, + 0.029588229954242706, + 0.1411418467760086, + -0.08631375432014465 + ] + }, + { + "id": "/en/ghost_rider_2007", + "initial_release_date": "2007-01-15", + "name": "Ghost Rider", + "genre": [ + "Adventure Film", + "Thriller", + "Fantasy", + "Superhero movie", + "Horror", + "Drama" + ], + "directed_by": [ + "Mark Steven Johnson" + ], + "film_vector": [ + -0.4613516330718994, + -0.29745200276374817, + -0.21249952912330627, + 0.3353015184402466, + -0.1648562252521515, + -0.10490388423204422, + -0.016861682757735252, + -0.07684136927127838, + -0.009413838386535645, + -0.0066701327450573444 + ] + }, + { + "id": "/en/ghost_ship_2002", + "initial_release_date": "2002-10-22", + "name": "Ghost Ship", + "genre": [ + "Horror", + "Supernatural", + "Slasher" + ], + "directed_by": [ + "Steve Beck" + ], + "film_vector": [ + -0.37423187494277954, + -0.39146727323532104, + -0.0651889219880104, + 0.15855836868286133, + -0.08048953115940094, + 0.05124959349632263, + 0.25269728899002075, + 0.12757280468940735, + 0.14809033274650574, + -0.08541935682296753 + ] + }, + { + "id": "/en/ghost_world_2001", + "initial_release_date": "2001-06-16", + "name": "Ghost World", + "genre": [ + "Indie film", + "Comedy-drama" + ], + "directed_by": [ + "Terry Zwigoff" + ], + "film_vector": [ + -0.18196488916873932, + -0.21275432407855988, + -0.1640510857105255, + 0.09559350460767746, + 0.21870502829551697, + -0.25773221254348755, + 0.19485530257225037, + -0.07267728447914124, + 0.25125250220298767, + -0.21077312529087067 + ] + }, + { + "id": "/en/ghosts_of_mars", + "initial_release_date": "2001-08-24", + "name": "Ghosts of Mars", + "genre": [ + "Adventure Film", + "Science Fiction", + "Horror", + "Supernatural", + "Action Film", + "Thriller", + "Space Western" + ], + "directed_by": [ + "John Carpenter" + ], + "film_vector": [ + -0.4216175675392151, + -0.3015602231025696, + -0.051768336445093155, + 0.2704084813594818, + 0.04996548965573311, + -0.1793140172958374, + 0.0840291827917099, + 0.001357104629278183, + 0.045443203300237656, + -0.09500658512115479 + ] + }, + { + "id": "/m/06ry42", + "initial_release_date": "2004-10-28", + "name": "The International Playboys' First Movie: Ghouls Gone Wild!", + "genre": [ + "Short Film", + "Musical" + ], + "directed_by": [ + "Ted Geoghegan" + ], + "film_vector": [ + -0.0077057043090462685, + -0.08666560053825378, + -0.06151672452688217, + 0.1373380720615387, + 0.09809960424900055, + -0.277605265378952, + 0.15526209771633148, + 0.03973304107785225, + 0.1962389051914215, + -0.2337753176689148 + ] + }, + { + "id": "/en/gie", + "initial_release_date": "2005-07-14", + "name": "Gie", + "genre": [ + "Biographical film", + "Political drama", + "Drama" + ], + "directed_by": [ + "Riri Riza" + ], + "film_vector": [ + -0.25848981738090515, + 0.15235397219657898, + -0.07845187187194824, + -0.24033358693122864, + -0.021731963381171227, + -0.22597408294677734, + -0.12692302465438843, + -0.010261781513690948, + 0.06464599817991257, + -0.28238093852996826 + ] + }, + { + "id": "/en/gigantic_2003", + "initial_release_date": "2003-03-10", + "name": "Gigantic (A Tale of Two Johns)", + "genre": [ + "Indie film", + "Documentary film" + ], + "directed_by": [ + "A. J. Schnack" + ], + "film_vector": [ + -0.0737413614988327, + -0.10021694004535675, + -0.14699992537498474, + 0.12954165041446686, + 0.16660752892494202, + -0.38919562101364136, + -0.06724139302968979, + -0.06299944967031479, + 0.1353326141834259, + -0.24736182391643524 + ] + }, + { + "id": "/en/gigli", + "initial_release_date": "2003-07-27", + "name": "Gigli", + "genre": [ + "Crime Thriller", + "Romance Film", + "Romantic comedy", + "Crime Fiction", + "Comedy" + ], + "directed_by": [ + "Martin Brest" + ], + "film_vector": [ + -0.4733155369758606, + -0.1477162390947342, + -0.44643306732177734, + 0.039387717843055725, + 0.08955095708370209, + -0.19417217373847961, + -0.020418504253029823, + 0.0025867903605103493, + -0.05790724605321884, + -0.10908878594636917 + ] + }, + { + "id": "/en/ginger_snaps", + "initial_release_date": "2000-09-10", + "name": "Ginger Snaps", + "genre": [ + "Teen film", + "Horror", + "Cult film" + ], + "directed_by": [ + "John Fawcett" + ], + "film_vector": [ + -0.11269844323396683, + -0.15853148698806763, + -0.16538821160793304, + 0.2494206726551056, + 0.25621724128723145, + -0.16400155425071716, + 0.1252436637878418, + 0.05246405303478241, + 0.2036885917186737, + -0.19902411103248596 + ] + }, + { + "id": "/en/ginger_snaps_2_unleashed", + "initial_release_date": "2004-01-30", + "name": "Ginger Snaps 2: Unleashed", + "genre": [ + "Thriller", + "Horror", + "Teen film", + "Creature Film", + "Feminist Film", + "Horror comedy", + "Comedy" + ], + "directed_by": [ + "Brett Sullivan" + ], + "film_vector": [ + -0.283054381608963, + -0.13959570229053497, + -0.28380799293518066, + 0.2941966652870178, + 0.12937328219413757, + -0.1924757957458496, + 0.08485414832830429, + 0.06330741941928864, + 0.14092057943344116, + -0.0679474025964737 + ] + }, + { + "id": "/en/girlfight", + "initial_release_date": "2000-01-22", + "name": "Girlfight", + "genre": [ + "Teen film", + "Sports", + "Coming-of-age story", + "Drama" + ], + "directed_by": [ + "Karyn Kusama" + ], + "film_vector": [ + -0.23037709295749664, + -0.0021087266504764557, + -0.22466661036014557, + -0.023925799876451492, + 0.10155822336673737, + -0.05517561733722687, + -0.2776950001716614, + -0.23409432172775269, + 0.18960705399513245, + 0.01437201164662838 + ] + }, + { + "id": "/en/gladiator_2000", + "initial_release_date": "2000-05-01", + "name": "Gladiator", + "genre": [ + "Historical drama", + "Epic film", + "Action Film", + "Adventure Film", + "Drama" + ], + "directed_by": [ + "Ridley Scott" + ], + "film_vector": [ + -0.41265419125556946, + 0.04229708015918732, + -0.09352448582649231, + 0.04410360008478165, + -0.06549455970525742, + -0.1977822184562683, + -0.2661505341529846, + 0.13072244822978973, + -0.19112294912338257, + -0.12292566895484924 + ] + }, + { + "id": "/en/glastonbury_2006", + "initial_release_date": "2006-04-14", + "name": "Glastonbury", + "genre": [ + "Documentary film", + "Music", + "Concert film", + "Biographical film" + ], + "directed_by": [ + "Julien Temple" + ], + "film_vector": [ + -0.14767107367515564, + 0.0012127570807933807, + -0.06273465603590012, + -0.04388221353292465, + -0.0658293142914772, + -0.5113402605056763, + -0.17392262816429138, + 0.11278624832630157, + 0.2531735301017761, + 0.017460256814956665 + ] + }, + { + "id": "/en/glastonbury_anthems", + "name": "Glastonbury Anthems", + "genre": [ + "Documentary film", + "Music", + "Concert film" + ], + "directed_by": [ + "Gavin Taylor", + "Declan Lowney", + "Janet Fraser-Crook", + "Phil Heyes" + ], + "film_vector": [ + 0.013146312907338142, + 0.04427026957273483, + 0.01654963567852974, + -0.06354714930057526, + 0.002732896711677313, + -0.4212656617164612, + -0.1947634518146515, + 0.17670895159244537, + 0.23263704776763916, + 0.07229720056056976 + ] + }, + { + "id": "/en/glitter_2001", + "initial_release_date": "2001-09-21", + "name": "Glitter", + "genre": [ + "Musical", + "Romance Film", + "Musical Drama", + "Drama" + ], + "directed_by": [ + "Vondie Curtis-Hall" + ], + "film_vector": [ + -0.2987813651561737, + 0.1576848328113556, + -0.5116472840309143, + -0.035073958337306976, + 0.041155435144901276, + -0.05836635082960129, + -0.14352549612522125, + 0.15152326226234436, + 0.0937899500131607, + -0.002493851585313678 + ] + }, + { + "id": "/en/global_heresy", + "initial_release_date": "2002-09-03", + "name": "Global Heresy", + "genre": [ + "Comedy" + ], + "directed_by": [ + "Sidney J. Furie" + ], + "film_vector": [ + 0.10827656090259552, + 0.019281737506389618, + -0.034153468906879425, + -0.07436379790306091, + -0.08192353695631027, + -0.010786330327391624, + 0.2032128870487213, + 0.13792505860328674, + -0.04567471146583557, + -0.15234610438346863 + ] + }, + { + "id": "/en/glory_road_2006", + "initial_release_date": "2006-01-13", + "name": "Glory Road", + "genre": [ + "Sports", + "Historical period drama", + "Docudrama", + "Drama" + ], + "directed_by": [ + "James Gartner" + ], + "film_vector": [ + -0.2696182131767273, + 0.2212323546409607, + -0.007168465759605169, + -0.177235409617424, + -0.1770695447921753, + -0.10353510081768036, + -0.17385664582252502, + -0.0474950410425663, + 0.03425915539264679, + -0.09694759547710419 + ] + }, + { + "id": "/en/go_figure_2005", + "initial_release_date": "2005-06-10", + "name": "Go Figure", + "genre": [ + "Family", + "Comedy", + "Drama" + ], + "directed_by": [ + "Francine McDougall" + ], + "film_vector": [ + -0.12066259980201721, + 0.10043875128030777, + -0.40125352144241333, + 0.00773494690656662, + -0.3019964098930359, + 0.15843503177165985, + 0.08307249844074249, + -0.20530028641223907, + 0.09172482788562775, + -0.04270094260573387 + ] + }, + { + "id": "/en/goal__2005", + "initial_release_date": "2005-09-08", + "name": "Goal!", + "genre": [ + "Sports", + "Romance Film", + "Drama" + ], + "directed_by": [ + "Danny Cannon" + ], + "film_vector": [ + -0.42978155612945557, + 0.1456017643213272, + -0.310641884803772, + -0.00018627941608428955, + -0.16982613503932953, + 0.07470439374446869, + -0.1826038658618927, + -0.20273491740226746, + 0.19186240434646606, + -0.06772421300411224 + ] + }, + { + "id": "/en/goal_2_living_the_dream", + "initial_release_date": "2007-02-09", + "name": "Goal II: Living the Dream", + "genre": [ + "Sports", + "Drama" + ], + "directed_by": [ + "Jaume Collet-Serra" + ], + "film_vector": [ + 0.06267605721950531, + 0.028248349204659462, + -0.1096162348985672, + -0.24113859236240387, + -0.03386829048395157, + 0.09686256945133209, + -0.23752889037132263, + -0.10982178151607513, + 0.11320140957832336, + 0.068234384059906 + ] + }, + { + "id": "/en/god_grew_tired_of_us", + "initial_release_date": "2006-09-04", + "name": "God Grew Tired of Us", + "genre": [ + "Documentary film", + "Indie film", + "Historical fiction" + ], + "directed_by": [ + "Christopher Dillon Quinn", + "Tommy Walker" + ], + "film_vector": [ + -0.10995715856552124, + 0.13519757986068726, + 0.026328660547733307, + -0.026918619871139526, + -0.13507778942584991, + -0.23847614228725433, + -0.04572226107120514, + -0.029435565695166588, + 0.0767829492688179, + -0.14442230761051178 + ] + }, + { + "id": "/en/god_on_my_side", + "initial_release_date": "2006-11-02", + "name": "God on My Side", + "genre": [ + "Documentary film", + "Christian film" + ], + "directed_by": [ + "Andrew Denton" + ], + "film_vector": [ + 0.007021032273769379, + 0.015200946480035782, + -0.050570908933877945, + -0.011484134942293167, + 0.16374582052230835, + -0.3365262746810913, + -0.11547084152698517, + -0.12923192977905273, + 0.15662512183189392, + -0.09711472690105438 + ] + }, + { + "id": "/en/godavari", + "initial_release_date": "2006-05-19", + "name": "Godavari", + "genre": [ + "Romance Film", + "Drama", + "Tollywood", + "World cinema" + ], + "directed_by": [ + "Sekhar Kammula" + ], + "film_vector": [ + -0.5845826864242554, + 0.3720879554748535, + -0.05439652502536774, + 0.03600216656923294, + 0.13035738468170166, + -0.07202672958374023, + 0.12518629431724548, + -0.10594667494297028, + 0.039797961711883545, + -0.10567165911197662 + ] + }, + { + "id": "/en/godfather", + "initial_release_date": "2006-02-24", + "name": "Varalaru", + "genre": [ + "Action Film", + "Musical", + "Romance Film", + "Tamil cinema", + "Drama", + "Musical Drama" + ], + "directed_by": [ + "K. S. Ravikumar" + ], + "film_vector": [ + -0.5264068841934204, + 0.36478090286254883, + -0.12303923070430756, + 0.07832911610603333, + 0.12754204869270325, + -0.11566875874996185, + -0.009104060009121895, + 0.08735498785972595, + -0.053811825811862946, + 0.02380458451807499 + ] + }, + { + "id": "/en/godsend", + "initial_release_date": "2004-04-30", + "name": "Godsend", + "genre": [ + "Thriller", + "Science Fiction", + "Horror", + "Psychological thriller", + "Sci-Fi Horror", + "Drama" + ], + "directed_by": [ + "Nick Hamm" + ], + "film_vector": [ + -0.5840650796890259, + -0.3181617259979248, + -0.30442655086517334, + -0.015701010823249817, + -0.13554774224758148, + -0.014628148637712002, + 0.05985972285270691, + 0.12033611536026001, + 0.06033388152718544, + -0.016178429126739502 + ] + }, + { + "id": "/en/godzilla_3d_to_the_max", + "initial_release_date": "2007-09-12", + "name": "Godzilla 3D to the MAX", + "genre": [ + "Horror", + "Action Film", + "Science Fiction", + "Short Film" + ], + "directed_by": [ + "Keith Melton", + "Yoshimitsu Banno" + ], + "film_vector": [ + -0.39683467149734497, + -0.11167619377374649, + 0.1592285931110382, + 0.3002949357032776, + -0.11358259618282318, + -0.25668108463287354, + 0.0573204830288887, + 0.00941403303295374, + 0.05048835650086403, + -0.06489185243844986 + ] + }, + { + "id": "/en/godzilla_against_mechagodzilla", + "initial_release_date": "2002-12-15", + "name": "Godzilla Against Mechagodzilla", + "genre": [ + "Monster", + "Science Fiction", + "Cult film", + "World cinema", + "Action Film", + "Creature Film", + "Japanese Movies" + ], + "directed_by": [ + "Masaaki Tezuka" + ], + "film_vector": [ + -0.30078428983688354, + -0.09755517542362213, + 0.22093603014945984, + 0.3206900358200073, + -0.029861874878406525, + -0.23431727290153503, + 0.06674700230360031, + 0.10557900369167328, + -0.08542187511920929, + -0.035245977342128754 + ] + }, + { + "id": "/en/godzilla_vs_megaguirus", + "initial_release_date": "2000-11-03", + "name": "Godzilla vs. Megaguirus", + "genre": [ + "Monster", + "World cinema", + "Science Fiction", + "Cult film", + "Action Film", + "Creature Film", + "Japanese Movies" + ], + "directed_by": [ + "Masaaki Tezuka" + ], + "film_vector": [ + -0.3116297721862793, + -0.05479230731725693, + 0.24148020148277283, + 0.3034999668598175, + -0.07409099489450455, + -0.19013983011245728, + 0.007316471077501774, + 0.11802893877029419, + -0.1365135759115219, + -0.014883768744766712 + ] + }, + { + "id": "/en/godzilla_tokyo_sos", + "initial_release_date": "2003-11-03", + "name": "Godzilla: Tokyo SOS", + "genre": [ + "Monster", + "Fantasy", + "World cinema", + "Action/Adventure", + "Science Fiction", + "Cult film", + "Japanese Movies" + ], + "directed_by": [ + "Masaaki Tezuka" + ], + "film_vector": [ + -0.42507773637771606, + -0.05802024528384209, + 0.16126544773578644, + 0.32384753227233887, + -0.19176949560642242, + -0.14636439085006714, + -0.010103999637067318, + 0.08978530764579773, + 0.03615662828087807, + -0.10871952772140503 + ] + }, + { + "id": "/wikipedia/fr/Godzilla$002C_Mothra_and_King_Ghidorah$003A_Giant_Monsters_All-Out_Attack", + "initial_release_date": "2001-11-03", + "name": "Godzilla, Mothra and King Ghidorah: Giant Monsters All-Out Attack", + "genre": [ + "Science Fiction", + "Action Film", + "Adventure Film", + "Drama" + ], + "directed_by": [ + "Shusuke Kaneko" + ], + "film_vector": [ + -0.3261665105819702, + -0.04523002356290817, + 0.22209250926971436, + 0.30556032061576843, + -0.07579460740089417, + -0.14163723587989807, + -0.002511331345885992, + 0.09054452180862427, + -0.17530202865600586, + -0.04467134177684784 + ] + }, + { + "id": "/en/godzilla_final_wars", + "initial_release_date": "2004-11-29", + "name": "Godzilla: Final Wars", + "genre": [ + "Fantasy", + "Science Fiction", + "Monster movie" + ], + "directed_by": [ + "Ryuhei Kitamura" + ], + "film_vector": [ + -0.23326504230499268, + -0.12534835934638977, + 0.2625719904899597, + 0.34315159916877747, + -0.009539421647787094, + -0.17154131829738617, + -0.017412802204489708, + 0.07810702174901962, + -0.054621241986751556, + -0.050682634115219116 + ] + }, + { + "id": "/en/going_the_distance", + "initial_release_date": "2004-08-20", + "name": "Going the Distance", + "genre": [ + "Comedy" + ], + "directed_by": [ + "Mark Griffiths" + ], + "film_vector": [ + 0.16883938014507294, + 0.04345281794667244, + -0.30415505170822144, + 0.0256912000477314, + 0.029270097613334656, + -0.19984140992164612, + 0.16333672404289246, + -0.07290170341730118, + -0.08712448179721832, + -0.0848819762468338 + ] + }, + { + "id": "/en/going_to_the_mat", + "initial_release_date": "2004-03-19", + "name": "Going to the Mat", + "genre": [ + "Family", + "Sports", + "Drama" + ], + "directed_by": [ + "Stuart Gillard" + ], + "film_vector": [ + 0.013835130259394646, + 0.058010317385196686, + -0.21798524260520935, + -0.10597420483827591, + -0.12969258427619934, + 0.2602725028991699, + -0.1259600967168808, + -0.09051401913166046, + 0.11094462871551514, + 0.14230121672153473 + ] + }, + { + "id": "/en/going_upriver", + "initial_release_date": "2004-09-14", + "name": "Going Upriver", + "genre": [ + "Documentary film", + "War film", + "Political cinema" + ], + "directed_by": [ + "George Butler" + ], + "film_vector": [ + -0.290277361869812, + 0.1510956883430481, + 0.06500833481550217, + -0.06472862511873245, + -0.14001533389091492, + -0.445145845413208, + -0.1071968525648117, + -0.07011403143405914, + 0.2307347059249878, + -0.10326710343360901 + ] + }, + { + "id": "/en/golmaal", + "initial_release_date": "2006-07-14", + "name": "Golmaal: Fun Unlimited", + "genre": [ + "Musical", + "Musical comedy", + "Comedy" + ], + "directed_by": [ + "Rohit Shetty" + ], + "film_vector": [ + -0.003111785277724266, + 0.21612969040870667, + -0.25092417001724243, + 0.20435163378715515, + -0.054105471819639206, + 0.018152035772800446, + 0.07331007719039917, + 0.15713465213775635, + 0.029338251799345016, + -0.13941088318824768 + ] + }, + { + "id": "/en/gone_in_sixty_seconds", + "initial_release_date": "2000-06-05", + "name": "Gone in 60 Seconds", + "genre": [ + "Thriller", + "Action Film", + "Crime Fiction", + "Crime Thriller", + "Heist film", + "Action/Adventure" + ], + "directed_by": [ + "Dominic Sena" + ], + "film_vector": [ + -0.47518593072891235, + -0.3181842565536499, + -0.26869088411331177, + 0.03921569883823395, + -0.010778740048408508, + -0.22191327810287476, + -0.02263084426522255, + -0.13606798648834229, + -0.055239561945199966, + 0.0027316659688949585 + ] + }, + { + "id": "/en/good_bye_lenin", + "initial_release_date": "2003-02-09", + "name": "Good bye, Lenin!", + "genre": [ + "Romance Film", + "Comedy", + "Drama", + "Tragicomedy" + ], + "directed_by": [ + "Wolfgang Becker" + ], + "film_vector": [ + -0.16025760769844055, + 0.11843302845954895, + -0.15791478753089905, + -0.08714666962623596, + 0.032081205397844315, + -0.17426562309265137, + -0.009659401141107082, + 0.06399821490049362, + 0.018697688356041908, + -0.29063335061073303 + ] + }, + { + "id": "/en/good_luck_chuck", + "initial_release_date": "2007-06-13", + "name": "Good Luck Chuck", + "genre": [ + "Romance Film", + "Fantasy", + "Comedy", + "Drama" + ], + "directed_by": [ + "Mark Helfrich" + ], + "film_vector": [ + -0.4287008047103882, + 0.014066990464925766, + -0.34731602668762207, + 0.11371397972106934, + -0.06702850759029388, + -0.04722217470407486, + -0.058144208043813705, + -0.23768538236618042, + 0.13577623665332794, + -0.1973944902420044 + ] + }, + { + "id": "/en/good_night_and_good_luck", + "initial_release_date": "2005-09-01", + "name": "Good Night, and Good Luck", + "genre": [ + "Political drama", + "Historical drama", + "Docudrama", + "Biographical film", + "Historical fiction", + "Drama" + ], + "directed_by": [ + "George Clooney" + ], + "film_vector": [ + -0.424032986164093, + 0.12151506543159485, + -0.15920525789260864, + -0.1455395221710205, + -0.19503945112228394, + -0.09787335991859436, + -0.05308595672249794, + 0.04031509906053543, + 0.13786296546459198, + -0.27258244156837463 + ] + }, + { + "id": "/en/goodbye_dragon_inn", + "initial_release_date": "2003-12-12", + "name": "Goodbye, Dragon Inn", + "genre": [ + "Comedy-drama", + "Comedy of manners", + "Comedy", + "Drama" + ], + "directed_by": [ + "Tsai Ming-liang" + ], + "film_vector": [ + 0.06870101392269135, + 0.12757432460784912, + -0.29789572954177856, + 0.03135902062058449, + 0.10074719041585922, + -0.04338068515062332, + 0.08706723898649216, + 0.12202861905097961, + -0.0856560468673706, + -0.25182491540908813 + ] + }, + { + "id": "/en/gosford_park", + "initial_release_date": "2001-11-07", + "name": "Gosford Park", + "genre": [ + "Mystery", + "Drama" + ], + "directed_by": [ + "Robert Altman" + ], + "film_vector": [ + -0.05448845028877258, + -0.14034390449523926, + -0.09421538561582565, + -0.1739729344844818, + 0.10753154754638672, + 0.037363361567258835, + -0.03864751756191254, + 0.05551711842417717, + 0.04072513431310654, + -0.26106953620910645 + ] + }, + { + "id": "/en/gothika", + "initial_release_date": "2003-11-13", + "name": "Gothika", + "genre": [ + "Thriller", + "Horror", + "Psychological thriller", + "Supernatural", + "Crime Thriller", + "Mystery" + ], + "directed_by": [ + "Mathieu Kassovitz" + ], + "film_vector": [ + -0.611562967300415, + -0.3218158781528473, + -0.25266581773757935, + -0.036458972841501236, + -0.02193821407854557, + 0.07036718726158142, + 0.1519378423690796, + 0.1480976641178131, + 0.1495639979839325, + -0.02745531126856804 + ] + }, + { + "id": "/en/gotta_kick_it_up", + "name": "Gotta Kick It Up!", + "genre": [ + "Teen film", + "Television film", + "Children's/Family", + "Family" + ], + "directed_by": [ + "Ram\u00f3n Men\u00e9ndez" + ], + "film_vector": [ + -0.15438464283943176, + 0.03569251671433449, + -0.2993513345718384, + 0.16036123037338257, + -0.192959263920784, + -0.05744355916976929, + -0.11994612216949463, + -0.2694275677204132, + 0.2567397654056549, + 0.028207967057824135 + ] + }, + { + "id": "/en/goyas_ghosts", + "initial_release_date": "2006-11-08", + "name": "Goya's Ghosts", + "genre": [ + "Biographical film", + "War film", + "Drama" + ], + "directed_by": [ + "Milo\u0161 Forman" + ], + "film_vector": [ + -0.25896719098091125, + -0.03297891467809677, + 0.15415990352630615, + -0.0751991793513298, + 0.059023018926382065, + -0.2721046805381775, + 0.07318387180566788, + 0.18040457367897034, + 0.11921660602092743, + -0.26575636863708496 + ] + }, + { + "id": "/en/gozu", + "initial_release_date": "2003-07-12", + "name": "Gozu", + "genre": [ + "Horror", + "Surrealism", + "World cinema", + "Japanese Movies", + "Horror comedy", + "Comedy" + ], + "directed_by": [ + "Takashi Miike" + ], + "film_vector": [ + -0.4255978465080261, + -0.01164361834526062, + -0.06626434624195099, + 0.14741678535938263, + -0.22670328617095947, + -0.12590867280960083, + 0.27161285281181335, + 0.10289508104324341, + 0.2625736594200134, + -0.20987513661384583 + ] + }, + { + "id": "/en/grande_ecole", + "initial_release_date": "2004-02-04", + "name": "Grande \u00c9cole", + "genre": [ + "World cinema", + "LGBT", + "Romance Film", + "Gay", + "Gay Interest", + "Gay Themed", + "Ensemble Film", + "Erotic Drama", + "Drama" + ], + "directed_by": [ + "Robert Salis" + ], + "film_vector": [ + -0.3282245993614197, + 0.19860702753067017, + -0.3159182369709015, + -0.01403084583580494, + -0.0029240939766168594, + -0.11647094786167145, + -0.12293784320354462, + 0.18872307240962982, + 0.2064022719860077, + -0.14934754371643066 + ] + }, + { + "id": "/en/grandmas_boy", + "initial_release_date": "2006-01-06", + "name": "Grandma's Boy", + "genre": [ + "Stoner film", + "Comedy" + ], + "directed_by": [ + "Nicholaus Goossen" + ], + "film_vector": [ + 0.13842463493347168, + -0.06698954105377197, + -0.33049702644348145, + 0.23384308815002441, + 0.27665138244628906, + -0.2991200387477875, + 0.1240350753068924, + -0.1959713250398636, + 0.028462836518883705, + -0.14491364359855652 + ] + }, + { + "id": "/en/grayson_2004", + "initial_release_date": "2004-07-20", + "name": "Grayson", + "genre": [ + "Indie film", + "Fan film", + "Short Film" + ], + "directed_by": [ + "John Fiorella" + ], + "film_vector": [ + -0.1611447036266327, + -0.04498371109366417, + -0.16296957433223724, + 0.17478254437446594, + 0.026239383965730667, + -0.2562277019023895, + -0.04383207485079765, + -0.15405753254890442, + 0.26876404881477356, + -0.11808113753795624 + ] + }, + { + "id": "/en/grbavica_2006", + "initial_release_date": "2006-02-12", + "name": "Grbavica: The Land of My Dreams", + "genre": [ + "War film", + "Art film", + "Drama" + ], + "directed_by": [ + "Jasmila \u017dbani\u0107" + ], + "film_vector": [ + -0.2951931953430176, + 0.15666648745536804, + 0.07183130830526352, + 0.029438292607665062, + 0.10703137516975403, + -0.27442505955696106, + -0.12116300314664841, + 0.03611838445067406, + 0.10976271331310272, + -0.2302425652742386 + ] + }, + { + "id": "/en/green_street", + "initial_release_date": "2005-03-12", + "name": "Green Street", + "genre": [ + "Sports", + "Crime Fiction", + "Drama" + ], + "directed_by": [ + "Lexi Alexander" + ], + "film_vector": [ + -0.2691422998905182, + -0.1640949845314026, + -0.1552036702632904, + -0.19774676859378815, + -0.2660982608795166, + 0.0794568881392479, + -0.06793205440044403, + -0.33973413705825806, + 0.04538346827030182, + -0.17464572191238403 + ] + }, + { + "id": "/en/green_tea_2003", + "initial_release_date": "2003-08-18", + "name": "Green Tea", + "genre": [ + "Romance Film", + "Drama" + ], + "directed_by": [ + "Zhang Yuan" + ], + "film_vector": [ + -0.13554029166698456, + 0.03683844581246376, + -0.3154928684234619, + 0.029756629839539528, + 0.37770670652389526, + -0.08308044821023941, + -0.05038832500576973, + -0.15465271472930908, + 0.0686614140868187, + -0.23680652678012848 + ] + }, + { + "id": "/en/greenfingers", + "initial_release_date": "2001-09-14", + "name": "Greenfingers", + "genre": [ + "Comedy-drama", + "Prison film", + "Comedy", + "Drama" + ], + "directed_by": [ + "Joel Hershman" + ], + "film_vector": [ + -0.06318683922290802, + -0.11989474296569824, + -0.20756995677947998, + -0.02658512443304062, + 0.14038485288619995, + -0.17702625691890717, + 0.060112059116363525, + -0.08301767706871033, + -0.12789314985275269, + -0.26909393072128296 + ] + }, + { + "id": "/en/gridiron_gang", + "initial_release_date": "2006-09-15", + "name": "Gridiron Gang", + "genre": [ + "Sports", + "Crime Fiction", + "Drama" + ], + "directed_by": [ + "Phil Joanou" + ], + "film_vector": [ + -0.13269533216953278, + -0.21439236402511597, + -0.12066087126731873, + -0.2751517593860626, + -0.2501281797885895, + 0.08166853338479996, + -0.12550219893455505, + -0.26372095942497253, + -0.08914241939783096, + -0.05826379731297493 + ] + }, + { + "id": "/en/grill_point", + "initial_release_date": "2002-02-12", + "name": "Grill Point", + "genre": [ + "Drama", + "Comedy", + "Tragicomedy", + "Comedy-drama" + ], + "directed_by": [ + "Andreas Dresen" + ], + "film_vector": [ + -0.14988642930984497, + 0.035541146993637085, + -0.44235947728157043, + -0.17324012517929077, + -0.1662585586309433, + -0.02155572921037674, + -0.022864436730742455, + 0.1365334689617157, + -0.03787586838006973, + -0.17112505435943604 + ] + }, + { + "id": "/en/grilled", + "initial_release_date": "2006-07-11", + "name": "Grilled", + "genre": [ + "Black comedy", + "Buddy film", + "Workplace Comedy", + "Comedy" + ], + "directed_by": [ + "Jason Ensler" + ], + "film_vector": [ + -0.07436368614435196, + 0.0014048591256141663, + -0.5191795825958252, + 0.045665375888347626, + -0.269706666469574, + -0.29221415519714355, + 0.25130194425582886, + -0.124079629778862, + -0.058296043425798416, + -0.1651003658771515 + ] + }, + { + "id": "/en/grind_house", + "initial_release_date": "2007-04-06", + "name": "Grindhouse", + "genre": [ + "Slasher", + "Thriller", + "Action Film", + "Horror", + "Zombie Film" + ], + "directed_by": [ + "Robert Rodriguez", + "Quentin Tarantino", + "Eli Roth", + "Edgar Wright", + "Rob Zombie", + "Jason Eisener" + ], + "film_vector": [ + -0.5008544325828552, + -0.38619428873062134, + -0.29498717188835144, + 0.12163477391004562, + 0.029919778928160667, + -0.24117116630077362, + 0.15595993399620056, + 0.06700149923563004, + 0.04421722888946533, + 0.07424452155828476 + ] + }, + { + "id": "/en/grizzly_falls", + "initial_release_date": "2004-06-28", + "name": "Grizzly Falls", + "genre": [ + "Adventure Film", + "Animal Picture", + "Family-Oriented Adventure", + "Family", + "Drama" + ], + "directed_by": [ + "Stewart Raffill" + ], + "film_vector": [ + -0.09320516884326935, + -0.11523465812206268, + -0.12562310695648193, + 0.42483168840408325, + -0.028125494718551636, + -0.18676277995109558, + -0.1634352207183838, + -0.11217634379863739, + 0.018192503601312637, + -0.1441541612148285 + ] + }, + { + "id": "/en/grizzly_man", + "initial_release_date": "2005-01-24", + "name": "Grizzly Man", + "genre": [ + "Documentary film", + "Biographical film" + ], + "directed_by": [ + "Werner Herzog" + ], + "film_vector": [ + -0.0013865437358617783, + -0.12356290221214294, + 0.04007962346076965, + 0.13921406865119934, + 0.013256052508950233, + -0.5035476088523865, + -0.0684347152709961, + -0.10809953510761261, + -0.008755749091506004, + -0.1578245460987091 + ] + }, + { + "id": "/en/grodmin", + "name": "GRODMIN", + "genre": [ + "Avant-garde", + "Experimental film", + "Drama" + ], + "directed_by": [ + "Jim Horwitz" + ], + "film_vector": [ + -0.17998985946178436, + 0.08122525364160538, + 0.006893601268529892, + -0.04874614626169205, + 0.03600805997848511, + -0.28816455602645874, + 0.04269153252243996, + 0.06875572353601456, + 0.28569599986076355, + -0.2559316158294678 + ] + }, + { + "id": "/en/gudumba_shankar", + "initial_release_date": "2004-09-09", + "name": "Gudumba Shankar", + "genre": [ + "Action Film", + "Drama", + "Tollywood", + "World cinema" + ], + "directed_by": [ + "Veera Shankar" + ], + "film_vector": [ + -0.43210935592651367, + 0.36123019456863403, + 0.08748946338891983, + 0.04857340455055237, + 0.05078529566526413, + -0.24997606873512268, + 0.1743449717760086, + -0.13718751072883606, + -0.11837021261453629, + -0.08385675400495529 + ] + }, + { + "id": "/en/che_part_two", + "initial_release_date": "2008-05-21", + "name": "Che: Part Two", + "genre": [ + "Biographical film", + "War film", + "Historical drama", + "Drama" + ], + "directed_by": [ + "Steven Soderbergh" + ], + "film_vector": [ + -0.2515902519226074, + 0.09709052741527557, + 0.05179544538259506, + -0.22110041975975037, + 0.02182845026254654, + -0.3610369563102722, + -0.15805163979530334, + -0.020153090357780457, + -0.07109556347131729, + -0.20263215899467468 + ] + }, + { + "id": "/en/guess_who_2005", + "initial_release_date": "2005-03-25", + "name": "Guess Who", + "genre": [ + "Romance Film", + "Romantic comedy", + "Comedy of manners", + "Domestic Comedy", + "Comedy" + ], + "directed_by": [ + "Kevin Rodney Sullivan" + ], + "film_vector": [ + -0.3118593394756317, + 0.11674303561449051, + -0.5978270173072815, + 0.10639505088329315, + 0.15770810842514038, + -0.15285144746303558, + 0.04435050114989281, + 0.01519730594009161, + -0.06312701851129532, + -0.23230770230293274 + ] + }, + { + "id": "/en/gunner_palace", + "initial_release_date": "2005-03-04", + "name": "Gunner Palace", + "genre": [ + "Documentary film", + "Indie film", + "War film" + ], + "directed_by": [ + "Michael Tucker", + "Petra Epperlein" + ], + "film_vector": [ + -0.21856671571731567, + 0.050985679030418396, + 0.02901238203048706, + -0.002785705029964447, + 0.06752774864435196, + -0.4849352240562439, + -0.14330564439296722, + -0.07642155885696411, + 0.12012772262096405, + -0.20348359644412994 + ] + }, + { + "id": "/en/guru_2007", + "initial_release_date": "2007-01-12", + "name": "Guru", + "genre": [ + "Biographical film", + "Musical", + "Romance Film", + "Drama", + "Musical Drama" + ], + "directed_by": [ + "Mani Ratnam" + ], + "film_vector": [ + -0.41816839575767517, + 0.2876896262168884, + -0.22396841645240784, + -0.006735045462846756, + 0.08671925961971283, + -0.21120434999465942, + 0.018968230113387108, + 0.08317825198173523, + -0.11242756247520447, + -0.049878835678100586 + ] + }, + { + "id": "/en/primeval_2007", + "initial_release_date": "2007-01-12", + "name": "Primeval", + "genre": [ + "Thriller", + "Horror", + "Natural horror film", + "Action/Adventure", + "Action Film" + ], + "directed_by": [ + "Michael Katleman" + ], + "film_vector": [ + -0.5830206274986267, + -0.2936563491821289, + -0.19273284077644348, + 0.19254973530769348, + 0.03286776319146156, + -0.18862663209438324, + -0.008477220311760902, + 0.1284344494342804, + 0.002883879467844963, + -0.0031519392505288124 + ] + }, + { + "id": "/en/gypsy_83", + "name": "Gypsy 83", + "genre": [ + "Coming of age", + "LGBT", + "Black comedy", + "Indie film", + "Comedy-drama", + "Road movie", + "Comedy", + "Drama" + ], + "directed_by": [ + "Todd Stephens" + ], + "film_vector": [ + -0.15107177197933197, + 0.10564453154802322, + -0.38909727334976196, + 0.030749782919883728, + 0.0013886881060898304, + -0.26570677757263184, + 0.0015609590336680412, + -0.044739820063114166, + 0.26330703496932983, + -0.1742679476737976 + ] + }, + { + "id": "/en/h_2002", + "initial_release_date": "2002-12-27", + "name": "H", + "genre": [ + "Thriller", + "Horror", + "Drama", + "Mystery", + "Crime Fiction", + "East Asian cinema", + "World cinema" + ], + "directed_by": [ + "Jong-hyuk Lee" + ], + "film_vector": [ + -0.7395639419555664, + -0.05055245757102966, + -0.1326233446598053, + 0.01563621312379837, + -0.16476207971572876, + -0.08741725981235504, + 0.1241549551486969, + -0.009180523455142975, + 0.11716252565383911, + -0.15964540839195251 + ] + }, + { + "id": "/en/h_g_wells_the_war_of_the_worlds", + "initial_release_date": "2005-06-14", + "name": "H. G. Wells' The War of the Worlds", + "genre": [ + "Indie film", + "Steampunk", + "Science Fiction", + "Thriller" + ], + "directed_by": [ + "Timothy Hines" + ], + "film_vector": [ + -0.3455749750137329, + -0.22221827507019043, + 0.06598499417304993, + 0.05092830955982208, + 0.018187914043664932, + -0.21503832936286926, + -0.11363302171230316, + 0.00786533858627081, + 0.03438233211636543, + -0.21903881430625916 + ] + }, + { + "id": "/en/h_g_wells_war_of_the_worlds", + "initial_release_date": "2005-06-28", + "name": "H. G. Wells' War of the Worlds", + "genre": [ + "Indie film", + "Science Fiction", + "Thriller", + "Film adaptation", + "Action Film", + "Alien Film", + "Horror", + "Mockbuster", + "Drama" + ], + "directed_by": [ + "David Michael Latt" + ], + "film_vector": [ + -0.46763110160827637, + -0.17056700587272644, + -0.051732636988162994, + 0.0903787761926651, + -0.12900128960609436, + -0.3214515447616577, + -0.0913533866405487, + 0.13424232602119446, + -0.05366373062133789, + -0.08015590906143188 + ] + }, + { + "id": "/en/hadh_kar_di_aapne", + "initial_release_date": "2000-04-14", + "name": "Hadh Kar Di Aapne", + "genre": [ + "Romantic comedy", + "Bollywood" + ], + "directed_by": [ + "Manoj Agrawal" + ], + "film_vector": [ + -0.24921034276485443, + 0.31141507625579834, + -0.22132453322410583, + 0.07777856290340424, + 0.3864247798919678, + -0.0178743414580822, + 0.16980992257595062, + -0.12004338204860687, + -0.09070377051830292, + 0.016711754724383354 + ] + }, + { + "id": "/en/haggard_the_movie", + "initial_release_date": "2003-06-24", + "name": "Haggard: The Movie", + "genre": [ + "Indie film", + "Comedy" + ], + "directed_by": [ + "Bam Margera" + ], + "film_vector": [ + 0.08437585830688477, + -0.007989443838596344, + -0.19284436106681824, + -0.0866990014910698, + -0.0023706587962806225, + -0.32971546053886414, + 0.036245882511138916, + -0.07207785546779633, + 0.06433607637882233, + -0.20612725615501404 + ] + }, + { + "id": "/en/haiku_tunnel", + "name": "Haiku Tunnel", + "genre": [ + "Black comedy", + "Indie film", + "Satire", + "Workplace Comedy", + "Comedy" + ], + "directed_by": [ + "Jacob Kornbluth", + "Josh Kornbluth" + ], + "film_vector": [ + -0.20535914599895477, + 0.079167440533638, + -0.38999801874160767, + -0.04539402574300766, + -0.2057773917913437, + -0.18836799263954163, + 0.23720741271972656, + 0.04229660704731941, + 0.15388454496860504, + -0.11375731974840164 + ] + }, + { + "id": "/en/hairspray", + "initial_release_date": "2007-07-13", + "name": "Hairspray", + "genre": [ + "Musical", + "Romance Film", + "Comedy", + "Musical comedy" + ], + "directed_by": [ + "Adam Shankman" + ], + "film_vector": [ + -0.23200757801532745, + 0.06335262954235077, + -0.6103289723396301, + 0.138829305768013, + 0.014264222234487534, + -0.144802525639534, + -0.013028796762228012, + 0.1321066915988922, + 0.0963849425315857, + -0.049241580069065094 + ] + }, + { + "id": "/en/half_nelson", + "initial_release_date": "2006-01-23", + "name": "Half Nelson", + "genre": [ + "Social problem film", + "Drama" + ], + "directed_by": [ + "Ryan Fleck" + ], + "film_vector": [ + 0.016396520659327507, + -0.0480756051838398, + -0.059779223054647446, + -0.0953543558716774, + 0.15432056784629822, + -0.23335033655166626, + -0.12557610869407654, + -0.11178405582904816, + 0.01832297071814537, + -0.2328561544418335 + ] + }, + { + "id": "/en/half_life_2006", + "name": "Half-Life", + "genre": [ + "Fantasy", + "Indie film", + "Science Fiction", + "Fantasy Drama", + "Drama" + ], + "directed_by": [ + "Jennifer Phang" + ], + "film_vector": [ + -0.47667524218559265, + 0.0074090659618377686, + -0.17112456262111664, + 0.05181928351521492, + -0.2697509527206421, + -0.0114407017827034, + -0.10532474517822266, + 0.019109288230538368, + 0.22939394414424896, + -0.1416272521018982 + ] + }, + { + "id": "/en/halloween_resurrection", + "initial_release_date": "2002-07-12", + "name": "Halloween Resurrection", + "genre": [ + "Slasher", + "Horror", + "Cult film", + "Teen film" + ], + "directed_by": [ + "Rick Rosenthal" + ], + "film_vector": [ + -0.25569167733192444, + -0.428450345993042, + -0.1343296766281128, + 0.19023782014846802, + 0.1602621227502823, + -0.16136899590492249, + 0.23118856549263, + 0.11305104196071625, + 0.1912906914949417, + 0.00599436741322279 + ] + }, + { + "id": "/en/halloweentown_high", + "initial_release_date": "2004-10-08", + "name": "Halloweentown High", + "genre": [ + "Fantasy", + "Teen film", + "Fantasy Comedy", + "Comedy", + "Family" + ], + "directed_by": [ + "Mark A.Z. Dipp\u00e9" + ], + "film_vector": [ + -0.1745021641254425, + -0.22751572728157043, + -0.3027886152267456, + 0.24269191920757294, + -0.056218549609184265, + 0.06491966545581818, + 0.1073828786611557, + 0.040262237191200256, + 0.23943674564361572, + -0.19229421019554138 + ] + }, + { + "id": "/en/halloweentown_ii_kalabars_revenge", + "initial_release_date": "2001-10-12", + "name": "Halloweentown II: Kalabar's Revenge", + "genre": [ + "Fantasy", + "Children's Fantasy", + "Children's/Family", + "Family" + ], + "directed_by": [ + "Mary Lambert" + ], + "film_vector": [ + -0.06973888725042343, + -0.27565258741378784, + 0.01786063238978386, + 0.14633528888225555, + -0.01964542455971241, + 0.1683426797389984, + 0.0369441919028759, + 0.1691511869430542, + 0.0816759541630745, + -0.16688323020935059 + ] + }, + { + "id": "/en/halloweentown_witch_u", + "initial_release_date": "2006-10-20", + "name": "Return to Halloweentown", + "genre": [ + "Family", + "Children's/Family", + "Fantasy Comedy", + "Comedy" + ], + "directed_by": [ + "David Jackson" + ], + "film_vector": [ + 0.014189109206199646, + -0.1990640014410019, + -0.27792561054229736, + 0.22174066305160522, + -0.15380632877349854, + 0.12142811715602875, + 0.1983882486820221, + -0.012830785475671291, + 0.16722314059734344, + -0.19596394896507263 + ] + }, + { + "id": "/en/hamlet_2000", + "initial_release_date": "2000-05-12", + "name": "Hamlet", + "genre": [ + "Thriller", + "Romance Film", + "Drama" + ], + "directed_by": [ + "Michael Almereyda" + ], + "film_vector": [ + -0.3947790265083313, + -0.07779473066329956, + -0.29101037979125977, + -0.07432739436626434, + 0.20847707986831665, + -0.06237214058637619, + -0.06421812623739243, + 0.07518448680639267, + 0.08679085969924927, + -0.22435957193374634 + ] + }, + { + "id": "/en/hana_alice", + "initial_release_date": "2004-03-13", + "name": "Hana and Alice", + "genre": [ + "Romance Film", + "Romantic comedy", + "Comedy", + "Drama" + ], + "directed_by": [ + "Shunji Iwai" + ], + "film_vector": [ + -0.20070356130599976, + 0.1369742453098297, + -0.3852977156639099, + 0.17142042517662048, + 0.24341681599617004, + 0.024176809936761856, + -0.07935723662376404, + 0.01973772421479225, + 0.12043299525976181, + -0.17498792707920074 + ] + }, + { + "id": "/en/hannibal", + "initial_release_date": "2001-02-09", + "name": "Hannibal", + "genre": [ + "Thriller", + "Psychological thriller", + "Horror", + "Action Film", + "Mystery", + "Crime Thriller", + "Drama" + ], + "directed_by": [ + "Ridley Scott" + ], + "film_vector": [ + -0.6017451286315918, + -0.3402631878852844, + -0.2966190278530121, + -0.03433768451213837, + -0.12994444370269775, + -0.09072801470756531, + 0.05444688722491264, + 0.04489672929048538, + -0.01964869722723961, + -0.03454922139644623 + ] + }, + { + "id": "/en/hans_och_hennes", + "initial_release_date": "2001-01-29", + "name": "Making Babies", + "genre": [ + "Drama" + ], + "directed_by": [ + "Daniel Lind Lagerl\u00f6f" + ], + "film_vector": [ + 0.13567084074020386, + 0.03511333465576172, + -0.14355462789535522, + -0.229201540350914, + 0.04315844178199768, + 0.2366114854812622, + -0.002256742911413312, + 0.02015245333313942, + 0.11551687866449356, + 0.07937201857566833 + ] + }, + { + "id": "/en/hanuman_2005", + "initial_release_date": "2005-10-21", + "name": "Hanuman", + "genre": [ + "Animation", + "Bollywood", + "World cinema" + ], + "directed_by": [ + "V.G. Samant", + "Milind Ukey" + ], + "film_vector": [ + -0.32015475630760193, + 0.42747026681900024, + 0.2262098640203476, + 0.2814728021621704, + -0.09597248584032059, + -0.07464294135570526, + 0.09288885444402695, + -0.09852337092161179, + 0.06356339901685715, + -0.12963630259037018 + ] + }, + { + "id": "/en/hanuman_junction", + "initial_release_date": "2001-12-21", + "name": "Hanuman Junction", + "genre": [ + "Action Film", + "Comedy", + "Drama", + "Tollywood", + "World cinema" + ], + "directed_by": [ + "M.Raja" + ], + "film_vector": [ + -0.35237663984298706, + 0.284812331199646, + -0.006082722917199135, + 0.19675861299037933, + 0.0526929572224617, + -0.14102210104465485, + 0.07046803086996078, + -0.0617862194776535, + -0.07321371138095856, + -0.11961036920547485 + ] + }, + { + "id": "/en/happily_never_after", + "initial_release_date": "2006-12-16", + "name": "Happily N'Ever After", + "genre": [ + "Fantasy", + "Animation", + "Family", + "Comedy", + "Adventure Film" + ], + "directed_by": [ + "Paul J. Bolger", + "Yvette Kaplan" + ], + "film_vector": [ + -0.23976856470108032, + 0.0971427708864212, + -0.3517676591873169, + 0.36007899045944214, + -0.0020500998944044113, + 0.12279090285301208, + -0.18174511194229126, + -0.041872892528772354, + 0.10307253897190094, + -0.1932697296142578 + ] + }, + { + "id": "/en/happy_2006", + "initial_release_date": "2006-01-27", + "name": "Happy", + "genre": [ + "Romance Film", + "Musical", + "Comedy", + "Drama", + "Musical comedy", + "Musical Drama" + ], + "directed_by": [ + "A. Karunakaran" + ], + "film_vector": [ + -0.25078877806663513, + 0.17519575357437134, + -0.6370413303375244, + 0.07805195450782776, + 0.06788972020149231, + -0.037423908710479736, + -0.15128330886363983, + 0.1569565236568451, + 0.004045912064611912, + -0.05875390022993088 + ] + }, + { + "id": "/en/happy_endings", + "initial_release_date": "2005-01-20", + "name": "Happy Endings", + "genre": [ + "LGBT", + "Music", + "Thriller", + "Romantic comedy", + "Indie film", + "Romance Film", + "Comedy", + "Drama" + ], + "directed_by": [ + "Don Roos" + ], + "film_vector": [ + -0.42895370721817017, + -0.07836151868104935, + -0.5445477962493896, + 0.08708146214485168, + -0.010076586157083511, + -0.053402651101350784, + -0.14154848456382751, + -0.06072543188929558, + 0.2128819227218628, + -0.0364953950047493 + ] + }, + { + "id": "/en/happy_ero_christmas", + "initial_release_date": "2003-12-17", + "name": "Happy Ero Christmas", + "genre": [ + "Romance Film", + "Comedy", + "East Asian cinema", + "World cinema" + ], + "directed_by": [ + "Lee Geon-dong" + ], + "film_vector": [ + -0.3202369809150696, + 0.3174590468406677, + -0.2563736140727997, + 0.2117912769317627, + 0.12681159377098083, + -0.08939599990844727, + 0.11243274807929993, + -0.012501749210059643, + 0.17872469127178192, + -0.20952193439006805 + ] + }, + { + "id": "/en/happy_feet", + "initial_release_date": "2006-11-16", + "name": "Happy Feet", + "genre": [ + "Family", + "Animation", + "Comedy", + "Music", + "Musical", + "Musical comedy" + ], + "directed_by": [ + "George Miller", + "Warren Coleman", + "Judy Morris" + ], + "film_vector": [ + 0.004671156406402588, + 0.11773678660392761, + -0.38884684443473816, + 0.35121479630470276, + -0.15254570543766022, + -0.012558226473629475, + -0.061469562351703644, + 0.04629601538181305, + 0.0858636349439621, + -0.12615469098091125 + ] + }, + { + "id": "/wikipedia/en_title/I_Love_New_Year", + "initial_release_date": "2013-12-30", + "name": "I Love New Year", + "genre": [ + "Caper story", + "Crime Fiction", + "Romantic comedy", + "Romance Film", + "Bollywood", + "World cinema" + ], + "directed_by": [ + "Radhika Rao", + "Vinay Sapru" + ], + "film_vector": [ + -0.5608586668968201, + 0.2235744595527649, + -0.1828320175409317, + 0.07286422699689865, + -0.06498456746339798, + 0.054159242659807205, + 0.1106555163860321, + -0.18785807490348816, + 0.07070352137088776, + -0.1079840436577797 + ] + }, + { + "id": "/en/har_dil_jo_pyar_karega", + "initial_release_date": "2000-07-24", + "name": "Har Dil Jo Pyar Karega", + "genre": [ + "Musical", + "Romance Film", + "World cinema", + "Musical Drama", + "Drama" + ], + "directed_by": [ + "Raj Kanwar" + ], + "film_vector": [ + -0.48481178283691406, + 0.44788336753845215, + -0.22245678305625916, + -0.023401273414492607, + 0.03979482129216194, + -0.09282879531383514, + 0.04063338041305542, + 0.08092941343784332, + 0.04246734455227852, + 0.006231712177395821 + ] + }, + { + "id": "/en/hard_candy", + "name": "Hard Candy", + "genre": [ + "Psychological thriller", + "Thriller", + "Suspense", + "Indie film", + "Erotic thriller", + "Drama" + ], + "directed_by": [ + "David Slade" + ], + "film_vector": [ + -0.5022213459014893, + -0.2479550838470459, + -0.436832070350647, + 0.02750466577708721, + 0.05957373231649399, + -0.1613152176141739, + 0.02603670209646225, + 0.03877872973680496, + 0.148972287774086, + -0.001196988858282566 + ] + }, + { + "id": "/en/hard_luck", + "initial_release_date": "2006-10-17", + "name": "Hard Luck", + "genre": [ + "Thriller", + "Crime Fiction", + "Action/Adventure", + "Action Film", + "Drama" + ], + "directed_by": [ + "Mario Van Peebles" + ], + "film_vector": [ + -0.6082878112792969, + -0.20309877395629883, + -0.3070248067378998, + 0.013091767206788063, + -0.10245829075574875, + -0.03654308617115021, + -0.035987384617328644, + -0.20384010672569275, + 0.0420708954334259, + -0.21158625185489655 + ] + }, + { + "id": "/en/hardball", + "initial_release_date": "2001-09-14", + "name": "Hardball", + "genre": [ + "Sports", + "Drama" + ], + "directed_by": [ + "Brian Robbins" + ], + "film_vector": [ + 0.04773136228322983, + 0.03396371752023697, + -0.17792776226997375, + -0.2884242832660675, + -0.1322561502456665, + 0.18771591782569885, + -0.17442110180854797, + -0.23907551169395447, + 0.005381045863032341, + 0.07339625805616379 + ] + }, + { + "id": "/en/harold_kumar_go_to_white_castle", + "initial_release_date": "2004-05-20", + "name": "Harold & Kumar Go to White Castle", + "genre": [ + "Stoner film", + "Buddy film", + "Adventure Film", + "Comedy" + ], + "directed_by": [ + "Danny Leiner" + ], + "film_vector": [ + -0.008320382796227932, + 0.011768711730837822, + -0.3666847348213196, + 0.24170219898223877, + 0.06276677548885345, + -0.29034721851348877, + 0.051648568361997604, + -0.13773247599601746, + -0.06485234200954437, + -0.1210733950138092 + ] + }, + { + "id": "/en/harry_potter_and_the_chamber_of_secrets_2002", + "initial_release_date": "2002-11-03", + "name": "Harry Potter and the Chamber of Secrets", + "genre": [ + "Adventure Film", + "Family", + "Fantasy", + "Mystery" + ], + "directed_by": [ + "Chris Columbus" + ], + "film_vector": [ + -0.275831401348114, + -0.14416906237602234, + -0.11316811293363571, + 0.2745105028152466, + 0.04061642661690712, + -0.0004262896254658699, + -0.12036335468292236, + 0.07888852059841156, + 0.03641737252473831, + -0.29541242122650146 + ] + }, + { + "id": "/en/harry_potter_and_the_goblet_of_fire_2005", + "initial_release_date": "2005-11-06", + "name": "Harry Potter and the Goblet of Fire", + "genre": [ + "Family", + "Fantasy", + "Adventure Film", + "Thriller", + "Science Fiction", + "Supernatural", + "Mystery", + "Children's Fantasy", + "Children's/Family", + "Fantasy Adventure", + "Fiction" + ], + "directed_by": [ + "Mike Newell" + ], + "film_vector": [ + -0.39153605699539185, + -0.12263825535774231, + -0.21567970514297485, + 0.19780687987804413, + -0.19199171662330627, + 0.09535939991474152, + -0.20379361510276794, + 0.22120913863182068, + -0.025170542299747467, + -0.21080052852630615 + ] + }, + { + "id": "/en/harry_potter_and_the_half_blood_prince_2008", + "initial_release_date": "2009-07-06", + "name": "Harry Potter and the Half-Blood Prince", + "genre": [ + "Adventure Film", + "Fantasy", + "Mystery", + "Action Film", + "Family", + "Romance Film", + "Children's Fantasy", + "Children's/Family", + "Fantasy Adventure", + "Fiction" + ], + "directed_by": [ + "David Yates" + ], + "film_vector": [ + -0.4124588370323181, + -0.05959142744541168, + -0.25364038348197937, + 0.3171447515487671, + -0.09414005279541016, + -0.03942094370722771, + -0.24373504519462585, + 0.20278434455394745, + -0.0963708758354187, + -0.14823219180107117 + ] + }, + { + "id": "/en/harry_potter_and_the_order_of_the_phoenix_2007", + "initial_release_date": "2007-06-28", + "name": "Harry Potter and the Order of the Phoenix", + "genre": [ + "Family", + "Mystery", + "Adventure Film", + "Fantasy", + "Fantasy Adventure", + "Fiction" + ], + "directed_by": [ + "David Yates" + ], + "film_vector": [ + -0.28193455934524536, + -0.12334723025560379, + -0.07736240327358246, + 0.24054911732673645, + -0.10441963374614716, + 0.13640080392360687, + -0.19986045360565186, + 0.09862971305847168, + -0.033493369817733765, + -0.327558696269989 + ] + } +] \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..aa6a022 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "solr-mcp-server" diff --git a/src/main/java/org/apache/solr/mcp/server/Main.java b/src/main/java/org/apache/solr/mcp/server/Main.java new file mode 100644 index 0000000..37549ae --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/Main.java @@ -0,0 +1,115 @@ +package org.apache.solr.mcp.server; + +import org.apache.solr.mcp.server.indexing.IndexingService; +import org.apache.solr.mcp.server.metadata.CollectionService; +import org.apache.solr.mcp.server.metadata.SchemaService; +import org.apache.solr.mcp.server.search.SearchService; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Main Spring Boot application class for the Apache Solr Model Context Protocol (MCP) Server. + * + *

This class serves as the entry point for the Solr MCP Server application, which provides a + * bridge between AI clients (such as Claude Desktop) and Apache Solr search and indexing + * capabilities through the Model Context Protocol specification. + * + *

Application Architecture: + * + *

The application follows a service-oriented architecture where each major Solr operation + * category is encapsulated in its own service class: + * + *

+ * + *

Spring Boot Features: + * + *

+ * + *

Communication Flow: + * + *

    + *
  1. AI client connects to MCP server via stdio + *
  2. Client discovers available tools through MCP protocol + *
  3. Client invokes tools with natural language parameters + *
  4. Server routes requests to appropriate service methods + *
  5. Services interact with Solr via SolrJ client library + *
  6. Results are serialized and returned to AI client + *
+ * + *

Configuration Requirements: + * + *

The application requires the following configuration properties: + * + *

{@code
+ * # application.properties
+ * solr.url=http://localhost:8983
+ * }
+ * + *

Deployment Considerations: + * + *

+ * + * @author adityamparikh + * @version 0.0.1 + * @see SearchService + * @see IndexingService + * @see CollectionService + * @see SchemaService + * @see org.springframework.boot.SpringApplication + * @since 0.0.1 + */ +@SpringBootApplication +public class Main { + + /** + * Main application entry point that starts the Spring Boot application. + * + *

This method initializes the Spring application context, configures all service beans, + * establishes Solr connectivity, and begins listening for MCP client connections via standard + * input/output. + * + *

Startup Process: + * + *

    + *
  1. Initialize Spring Boot application context + *
  2. Load configuration properties from various sources + *
  3. Create and configure SolrClient bean + *
  4. Initialize all service beans with dependency injection + *
  5. Register MCP tools from service methods + *
  6. Start MCP server listening on stdio + *
+ * + *

Error Handling: + * + *

Startup failures typically indicate configuration issues such as: + * + *

+ * + * @param args command-line arguments passed to the application + * @see SpringApplication#run(Class, String...) + */ + public static void main(String[] args) { + SpringApplication.run(Main.class, args); + } +} diff --git a/src/main/java/org/apache/solr/mcp/server/config/SolrConfig.java b/src/main/java/org/apache/solr/mcp/server/config/SolrConfig.java new file mode 100644 index 0000000..d3e1635 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/config/SolrConfig.java @@ -0,0 +1,151 @@ +package org.apache.solr.mcp.server.config; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.concurrent.TimeUnit; + +/** + * Spring Configuration class for Apache Solr client setup and connection management. + * + *

This configuration class is responsible for creating and configuring the SolrJ client that + * serves as the primary interface for communication with Apache Solr servers. It handles URL + * normalization, connection parameters, and timeout configurations to ensure reliable connectivity + * for the MCP server operations. + * + *

Configuration Features: + * + *

+ * + *

URL Processing: + * + *

The configuration automatically normalizes Solr URLs to ensure proper communication: + * + *

+ * + *

Connection Parameters: + * + *

+ * + *

Configuration Example: + * + *

{@code
+ * # application.properties
+ * solr.url=http://localhost:8983
+ *
+ * # Results in normalized URL: http://localhost:8983/solr/
+ * }
+ * + *

Supported URL Formats: + * + *

+ * + * @author adityamparikh + * @author dsmiley + * @version 0.0.1 + * @see SolrConfigurationProperties + * @see Http2SolrClient + * @see org.springframework.boot.context.properties.EnableConfigurationProperties + * @since 0.0.1 + */ +@Configuration +@EnableConfigurationProperties(SolrConfigurationProperties.class) +public class SolrConfig { + + private static final int CONNECTION_TIMEOUT_MS = 10000; + private static final int SOCKET_TIMEOUT_MS = 60000; + private static final String SOLR_PATH = "solr/"; + + /** + * Creates and configures a SolrClient bean for Apache Solr communication. + * + *

This method serves as the primary factory for creating SolrJ client instances that are + * used throughout the application for all Solr operations. It performs automatic URL + * normalization and applies production-ready timeout configurations. + * + *

URL Normalization Process: + * + *

    + *
  1. Trailing Slash: Ensures URL ends with "/" + *
  2. Solr Path: Appends "/solr/" if not already present + *
  3. Validation: Checks for proper Solr endpoint format + *
+ * + *

Connection Configuration: + * + *

+ * + *

Client Type: + * + *

Creates an {@code HttpSolrClient} configured for standard HTTP-based communication with + * Solr servers. This client type is suitable for both standalone Solr instances and SolrCloud + * deployments when used with load balancers. + * + *

Error Handling: + * + *

URL normalization is defensive and handles various input formats gracefully. Invalid URLs + * or connection failures will be caught during application startup or first usage, providing + * clear error messages for troubleshooting. + * + *

Production Considerations: + * + *

+ * + * @param properties the injected Solr configuration properties containing connection URL + * @return configured SolrClient instance ready for use in application services + * @see Http2SolrClient.Builder + * @see SolrConfigurationProperties#url() + */ + @Bean + SolrClient solrClient(SolrConfigurationProperties properties) { + String url = properties.url(); + + // Ensure URL is properly formatted for Solr + // The URL should end with /solr/ for proper path construction + if (!url.endsWith("/")) { + url = url + "/"; + } + + // If URL doesn't contain /solr/ path, add it + if (!url.endsWith("/" + SOLR_PATH) && !url.contains("/" + SOLR_PATH)) { + if (url.endsWith("/")) { + url = url + SOLR_PATH; + } else { + url = url + "/" + SOLR_PATH; + } + } + + // Use with explicit base URL + return new Http2SolrClient.Builder(url) + .withConnectionTimeout(CONNECTION_TIMEOUT_MS, TimeUnit.MILLISECONDS) + .withIdleTimeout(SOCKET_TIMEOUT_MS, TimeUnit.MILLISECONDS) + .build(); + } +} diff --git a/src/main/java/org/apache/solr/mcp/server/config/SolrConfigurationProperties.java b/src/main/java/org/apache/solr/mcp/server/config/SolrConfigurationProperties.java new file mode 100644 index 0000000..167cb64 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/config/SolrConfigurationProperties.java @@ -0,0 +1,83 @@ +package org.apache.solr.mcp.server.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Spring Boot Configuration Properties record for Apache Solr connection settings. + * + *

This immutable configuration record encapsulates all external configuration properties + * required for establishing and maintaining connections to Apache Solr servers. It follows Spring + * Boot's type-safe configuration properties pattern using Java records for enhanced immutability + * and reduced boilerplate. + * + *

Configuration Binding: + * + *

This record automatically binds to configuration properties with the "solr" prefix from + * various configuration sources including: + * + *

+ * + *

Record Benefits: + * + *

+ * + *

URL Format Requirements: + * + *

The Solr URL should point to the base Solr server endpoint. The configuration system will + * automatically normalize URLs to ensure proper formatting: + * + *

+ * + *

Environment-Specific Configuration: + * + *

{@code
+ * # Development
+ * solr.url=http://localhost:8983
+ *
+ * # Staging
+ * solr.url=http://solr-staging.company.com:8983
+ *
+ * # Production
+ * solr.url=https://solr-prod.company.com:8983
+ * }
+ * + *

Integration with Dependency Injection: + * + *

This record is automatically instantiated by Spring Boot's configuration properties mechanism + * and can be injected into any Spring-managed component that requires Solr connection information. + * + *

Validation Considerations: + * + *

While basic validation is handled by the configuration system, additional URL validation and + * normalization occurs in the {@link SolrConfig} class during SolrClient bean creation. + * + * @param url the base URL of the Apache Solr server (required, non-null) + * @author adityamparikh + * @version 0.0.1 + * @see SolrConfig + * @see org.springframework.boot.context.properties.ConfigurationProperties + * @see org.springframework.boot.context.properties.EnableConfigurationProperties + * @since 0.0.1 + */ +@ConfigurationProperties(prefix = "solr") +public record SolrConfigurationProperties(String url) { +} diff --git a/src/main/java/org/apache/solr/mcp/server/indexing/IndexingService.java b/src/main/java/org/apache/solr/mcp/server/indexing/IndexingService.java new file mode 100644 index 0000000..6c24432 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/indexing/IndexingService.java @@ -0,0 +1,365 @@ +package org.apache.solr.mcp.server.indexing; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.mcp.server.indexing.documentcreator.IndexingDocumentCreator; +import org.springaicommunity.mcp.annotation.McpTool; +import org.springaicommunity.mcp.annotation.McpToolParam; +import org.springframework.stereotype.Service; +import org.xml.sax.SAXException; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.util.List; + +/** + * Spring Service providing comprehensive document indexing capabilities for Apache Solr collections + * through Model Context Protocol (MCP) integration. + * + *

This service handles the conversion of JSON, CSV, and XML documents into Solr-compatible + * format and manages the indexing process with robust error handling and batch processing + * capabilities. It employs a schema-less approach where Solr automatically detects field types, + * eliminating the need for predefined schema configuration. + * + *

Core Features: + * + *

+ * + *

MCP Tool Integration: + * + *

The service exposes indexing functionality as MCP tools that can be invoked by AI clients + * through natural language requests. This enables seamless document ingestion workflows from + * external data sources. + * + *

JSON Document Processing: + * + *

The service processes JSON documents by flattening nested objects using underscore notation + * (e.g., "user.name" becomes "user_name") and handles arrays by converting them to multi-valued + * fields that Solr natively supports. + * + *

Batch Processing Strategy: + * + *

Uses configurable batch sizes (default 1000 documents) for optimal performance. If a batch + * fails, the service automatically retries by indexing documents individually to identify and skip + * problematic documents while preserving valid ones. + * + *

Example Usage: + * + *

{@code
+ * // Index JSON array of documents
+ * String jsonData = "[{\"title\":\"Document 1\",\"content\":\"Content here\"}]";
+ * indexingService.indexDocuments("my_collection", jsonData);
+ *
+ * // Programmatic document creation and indexing
+ * List docs = indexingService.createSchemalessDocuments(jsonData);
+ * int successful = indexingService.indexDocuments("my_collection", docs);
+ * }
+ * + * @author adityamparikh + * @version 0.0.1 + * @see SolrInputDocument + * @see SolrClient + * @see org.springframework.ai.tool.annotation.Tool + * @since 0.0.1 + */ +@Service +public class IndexingService { + + private static final int DEFAULT_BATCH_SIZE = 1000; + + /** + * SolrJ client for communicating with Solr server + */ + private final SolrClient solrClient; + + /** Service for creating SolrInputDocument objects from various data formats */ + private final IndexingDocumentCreator indexingDocumentCreator; + + /** + * Constructs a new IndexingService with the required dependencies. + * + *

This constructor is automatically called by Spring's dependency injection framework during + * application startup, providing the service with the necessary Solr client and configuration + * components. + * + * @param solrClient the SolrJ client instance for communicating with Solr + * @see SolrClient + */ + public IndexingService(SolrClient solrClient, IndexingDocumentCreator indexingDocumentCreator) { + this.solrClient = solrClient; + this.indexingDocumentCreator = indexingDocumentCreator; + } + + /** + * Indexes documents from a JSON string into a specified Solr collection. + * + *

This method serves as the primary entry point for document indexing operations and is + * exposed as an MCP tool for AI client interactions. It processes JSON data containing document + * arrays and indexes them using a schema-less approach. + * + *

Supported JSON Formats: + * + *

+ * + *

Processing Workflow: + * + *

    + *
  1. Parse JSON string into structured documents + *
  2. Convert to schema-less SolrInputDocument objects + *
  3. Execute batch indexing with error handling + *
  4. Commit changes to make documents searchable + *
+ * + *

MCP Tool Usage: + * + *

AI clients can invoke this method with natural language requests like "index these + * documents into my_collection" or "add this JSON data to the search index". + * + *

Error Handling: + * + *

If indexing fails, the method attempts individual document processing to maximize the + * number of successfully indexed documents. Detailed error information is logged for + * troubleshooting purposes. + * + * @param collection the name of the Solr collection to index documents into + * @param json JSON string containing an array of documents to index + * @throws IOException if there are critical errors in JSON parsing or Solr communication + * @throws SolrServerException if Solr server encounters errors during indexing + * @see IndexingDocumentCreator#createSchemalessDocumentsFromJson(String) + * @see #indexDocuments(String, List) + */ + @McpTool( + name = "index_json_documents", + description = "Index documents from json String into Solr collection") + public void indexJsonDocuments( + @McpToolParam(description = "Solr collection to index into") String collection, + @McpToolParam(description = "JSON string containing documents to index") String json) + throws IOException, SolrServerException { + List schemalessDoc = + indexingDocumentCreator.createSchemalessDocumentsFromJson(json); + indexDocuments(collection, schemalessDoc); + } + + /** + * Indexes documents from a CSV string into a specified Solr collection. + * + *

This method serves as the primary entry point for CSV document indexing operations and is + * exposed as an MCP tool for AI client interactions. It processes CSV data with headers and + * indexes them using a schema-less approach. + * + *

Supported CSV Formats: + * + *

+ * + *

Processing Workflow: + * + *

    + *
  1. Parse CSV string to extract headers and data rows + *
  2. Convert to schema-less SolrInputDocument objects + *
  3. Execute batch indexing with error handling + *
  4. Commit changes to make documents searchable + *
+ * + *

MCP Tool Usage: + * + *

AI clients can invoke this method with natural language requests like "index this CSV data + * into my_collection" or "add these CSV records to the search index". + * + *

Error Handling: + * + *

If indexing fails, the method attempts individual document processing to maximize the + * number of successfully indexed documents. Detailed error information is logged for + * troubleshooting purposes. + * + * @param collection the name of the Solr collection to index documents into + * @param csv CSV string containing documents to index (first row must be headers) + * @throws IOException if there are critical errors in CSV parsing or Solr communication + * @throws SolrServerException if Solr server encounters errors during indexing + * @see IndexingDocumentCreator#createSchemalessDocumentsFromCsv(String) + * @see #indexDocuments(String, List) + */ + @McpTool( + name = "index_csv_documents", + description = "Index documents from CSV string into Solr collection") + public void indexCsvDocuments( + @McpToolParam(description = "Solr collection to index into") String collection, + @McpToolParam(description = "CSV string containing documents to index") String csv) + throws IOException, SolrServerException { + List schemalessDoc = + indexingDocumentCreator.createSchemalessDocumentsFromCsv(csv); + indexDocuments(collection, schemalessDoc); + } + + /** + * Indexes documents from an XML string into a specified Solr collection. + * + *

This method serves as the primary entry point for XML document indexing operations and is + * exposed as an MCP tool for AI client interactions. It processes XML data with nested elements + * and attributes, indexing them using a schema-less approach. + * + *

Supported XML Formats: + * + *

+ * + *

Processing Workflow: + * + *

    + *
  1. Parse XML string to extract elements and attributes + *
  2. Flatten nested structures using underscore notation + *
  3. Convert to schema-less SolrInputDocument objects + *
  4. Execute batch indexing with error handling + *
  5. Commit changes to make documents searchable + *
+ * + *

MCP Tool Usage: + * + *

AI clients can invoke this method with natural language requests like "index this XML data + * into my_collection" or "add these XML records to the search index". + * + *

Error Handling: + * + *

If indexing fails, the method attempts individual document processing to maximize the + * number of successfully indexed documents. Detailed error information is logged for + * troubleshooting purposes. + * + *

Example XML Processing: + * + *

{@code
+     * Input:
+     * 
+     *   
+     *     Sample
+     *     
+     *       John Doe
+     *     
+     *   
+     * 
+     *
+     * Result: {id_attr:"1", title:"Sample", author_name:"John Doe"}
+     * }
+ * + * @param collection the name of the Solr collection to index documents into + * @param xml XML string containing documents to index + * @throws ParserConfigurationException if XML parser configuration fails + * @throws SAXException if XML parsing fails due to malformed content + * @throws IOException if I/O errors occur during parsing or Solr communication + * @throws SolrServerException if Solr server encounters errors during indexing + * @see IndexingDocumentCreator#createSchemalessDocumentsFromXml(String) + * @see #indexDocuments(String, List) + */ + @McpTool( + name = "index_xml_documents", + description = "Index documents from XML string into Solr collection") + public void indexXmlDocuments( + @McpToolParam(description = "Solr collection to index into") String collection, + @McpToolParam(description = "XML string containing documents to index") String xml) + throws ParserConfigurationException, SAXException, IOException, SolrServerException { + List schemalessDoc = + indexingDocumentCreator.createSchemalessDocumentsFromXml(xml); + indexDocuments(collection, schemalessDoc); + } + + /** + * Indexes a list of SolrInputDocument objects into a Solr collection using batch processing. + * + *

This method implements a robust batch indexing strategy that optimizes performance while + * providing resilience against individual document failures. It processes documents in + * configurable batches and includes fallback mechanisms for error recovery. + * + *

Batch Processing Strategy: + * + *

    + *
  • Batch Size: Configurable (default 1000) for optimal performance + *
  • Error Recovery: Individual document retry on batch failure + *
  • Success Tracking: Accurate count of successfully indexed documents + *
  • Commit Strategy: Single commit after all batches for consistency + *
+ * + *

Error Handling Workflow: + * + *

    + *
  1. Attempt batch indexing for optimal performance + *
  2. On batch failure, retry each document individually + *
  3. Track successful vs failed document counts + *
  4. Continue processing remaining batches despite failures + *
  5. Commit all successful changes at the end + *
+ * + *

Performance Considerations: + * + *

Batch processing significantly improves indexing performance compared to individual + * document operations. The fallback to individual processing ensures maximum document ingestion + * even when some documents have issues. + * + *

Transaction Behavior: + * + *

The method commits changes after all batches are processed, making indexed documents + * immediately searchable. This ensures atomicity at the operation level while maintaining + * performance through batching. + * + * @param collection the name of the Solr collection to index into + * @param documents list of SolrInputDocument objects to index + * @return the number of documents successfully indexed + * @throws SolrServerException if there are critical errors in Solr communication + * @throws IOException if there are critical errors in commit operations + * @see SolrInputDocument + * @see SolrClient#add(String, java.util.Collection) + * @see SolrClient#commit(String) + */ + public int indexDocuments(String collection, List documents) + throws SolrServerException, IOException { + int successCount = 0; + final int batchSize = DEFAULT_BATCH_SIZE; + + for (int i = 0; i < documents.size(); i += batchSize) { + final int endIndex = Math.min(i + batchSize, documents.size()); + final List batch = documents.subList(i, endIndex); + + try { + solrClient.add(collection, batch); + successCount += batch.size(); + } catch (SolrServerException | IOException | RuntimeException _) { + // Try indexing documents individually to identify problematic ones + for (SolrInputDocument doc : batch) { + try { + solrClient.add(collection, doc); + successCount++; + } catch (SolrServerException | IOException | RuntimeException _) { + // Document failed to index - this is expected behavior for problematic + // documents + // We continue processing the rest of the batch + } + } + } + } + + solrClient.commit(collection); + return successCount; + } +} diff --git a/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/CsvDocumentCreator.java b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/CsvDocumentCreator.java new file mode 100644 index 0000000..26e2375 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/CsvDocumentCreator.java @@ -0,0 +1,113 @@ +package org.apache.solr.mcp.server.indexing.documentcreator; + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVRecord; +import org.apache.solr.common.SolrInputDocument; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +/** + * Utility class for processing CSV documents and converting them to SolrInputDocument objects. + * + *

This class handles the conversion of CSV documents into Solr-compatible format using a + * schema-less approach where Solr automatically detects field types. + */ +@Component +public class CsvDocumentCreator implements SolrDocumentCreator { + + private static final int MAX_INPUT_SIZE_BYTES = 10 * 1024 * 1024; + + /** + * Creates a list of schema-less SolrInputDocument objects from a CSV string. + * + *

This method implements a flexible document conversion strategy that allows Solr to + * automatically detect field types without requiring predefined schema configuration. It + * processes CSV data by using the first row as field headers and converting each subsequent row + * into a document. + * + *

Schema-less Benefits: + * + *

    + *
  • Flexibility: No need to predefine field types in schema + *
  • Rapid Prototyping: Quick iteration on document structures + *
  • Type Detection: Solr automatically infers optimal field types + *
  • Dynamic Fields: Support for varying document structures + *
+ * + *

CSV Processing Rules: + * + *

    + *
  • Header Row: First row defines field names, automatically sanitized + *
  • Empty Values: Ignored and not indexed + *
  • Type Detection: Solr handles numeric, boolean, and string types + * automatically + *
  • Field Sanitization: Column names cleaned for Solr compatibility + *
+ * + *

Field Name Sanitization: + * + *

Field names are automatically sanitized to ensure Solr compatibility by removing special + * characters and converting to lowercase with underscore separators. + * + *

Example Transformation: + * + *

{@code
+     * Input CSV:
+     * id,name,price,inStock
+     * 123,Product A,19.99,true
+     *
+     * Output Document:
+     * {id:"123", name:"Product A", price:"19.99", instock:"true"}
+     * }
+ * + * @param csv CSV string containing document data (first row must be headers) + * @return list of SolrInputDocument objects ready for indexing + * @throws DocumentProcessingException if CSV parsing fails, input validation fails, or the + * structure is invalid + * @see SolrInputDocument + * @see FieldNameSanitizer#sanitizeFieldName(String) + */ + public List create(String csv) throws DocumentProcessingException { + if (csv.getBytes(StandardCharsets.UTF_8).length > MAX_INPUT_SIZE_BYTES) { + throw new DocumentProcessingException( + "Input too large: exceeds maximum size of " + MAX_INPUT_SIZE_BYTES + " bytes"); + } + + List documents = new ArrayList<>(); + + try (CSVParser parser = + new CSVParser( + new StringReader(csv), + CSVFormat.Builder.create().setHeader().setTrim(true).build())) { + List headers = new ArrayList<>(parser.getHeaderNames()); + headers.replaceAll(FieldNameSanitizer::sanitizeFieldName); + + for (CSVRecord csvRecord : parser) { + if (csvRecord.size() == 0) { + continue; // Skip empty lines + } + + SolrInputDocument doc = new SolrInputDocument(); + + for (int i = 0; i < headers.size() && i < csvRecord.size(); i++) { + String value = csvRecord.get(i); + if (!value.isEmpty()) { + doc.addField(headers.get(i), value); + } + } + + documents.add(doc); + } + } catch (IOException e) { + throw new DocumentProcessingException("Failed to parse CSV document", e); + } + + return documents; + } +} diff --git a/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/DocumentProcessingException.java b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/DocumentProcessingException.java new file mode 100644 index 0000000..e2ae3c7 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/DocumentProcessingException.java @@ -0,0 +1,53 @@ +package org.apache.solr.mcp.server.indexing.documentcreator; + +/** + * Exception thrown when document processing operations fail. + * + *

This exception provides a unified error handling mechanism for all document creator + * implementations, wrapping various underlying exceptions while preserving the original error + * context and stack trace information. + * + *

Common scenarios where this exception is thrown: + * + *

    + *
  • Invalid document format or structure + *
  • Document parsing errors (JSON, XML, CSV) + *
  • Input validation failures + *
  • Resource access or I/O errors during processing + *
+ */ +public class DocumentProcessingException extends RuntimeException { + + /** + * Constructs a new DocumentProcessingException with the specified detail message. + * + * @param message the detail message explaining the error + */ + public DocumentProcessingException(String message) { + super(message); + } + + /** + * Constructs a new DocumentProcessingException with the specified detail message and cause. + * + *

This constructor is particularly useful for wrapping underlying exceptions while providing + * additional context about the document processing failure. + * + * @param message the detail message explaining the error + * @param cause the cause of this exception (which is saved for later retrieval) + */ + public DocumentProcessingException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new DocumentProcessingException with the specified cause. + * + *

The detail message is automatically derived from the cause's toString() method. + * + * @param cause the cause of this exception (which is saved for later retrieval) + */ + public DocumentProcessingException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/FieldNameSanitizer.java b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/FieldNameSanitizer.java new file mode 100644 index 0000000..de46012 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/FieldNameSanitizer.java @@ -0,0 +1,95 @@ +package org.apache.solr.mcp.server.indexing.documentcreator; + +import java.util.regex.Pattern; + +/** + * Utility class for sanitizing field names to ensure compatibility with Solr's field naming + * requirements. + * + *

This class provides shared regex patterns and sanitization logic that can be used across all + * document creators to ensure consistent field name handling. + * + *

Solr has specific requirements for field names that must be met to ensure proper indexing and + * searching functionality. This utility transforms arbitrary field names into Solr-compliant + * identifiers. + */ +public final class FieldNameSanitizer { + + /** + * Pattern to match invalid characters in field names. Matches any character that is not + * alphanumeric or underscore. + */ + private static final Pattern INVALID_CHARACTERS_PATTERN = Pattern.compile("[\\W]"); + + /** + * Pattern to match leading and trailing underscores. Uses explicit grouping to make operator + * precedence clear. + */ + private static final Pattern LEADING_TRAILING_UNDERSCORES_PATTERN = + Pattern.compile("(^_+)|(_+$)"); + + /** + * Pattern to match multiple consecutive underscores. Matches two or more consecutive + * underscores to collapse them into one. + */ + private static final Pattern MULTIPLE_UNDERSCORES_PATTERN = Pattern.compile("_{2,}"); + + // Private constructor to prevent instantiation + private FieldNameSanitizer() { + throw new UnsupportedOperationException("Utility class cannot be instantiated"); + } + + /** + * Sanitizes field names to ensure they are compatible with Solr's field naming requirements. + * + *

Sanitization Rules: + * + *

    + *
  • Case Conversion: All characters converted to lowercase + *
  • Character Replacement: Non-alphanumeric characters replaced with + * underscores + *
  • Edge Trimming: Leading and trailing underscores removed + *
  • Duplicate Compression: Multiple consecutive underscores collapsed to + * single + *
  • Numeric Prefix: Field names starting with numbers get "field_" prefix + *
+ * + *

Example Transformations: + * + *

    + *
  • "User-Name" → "user_name" + *
  • "product.price" → "product_price" + *
  • "__field__name__" → "field_name" + *
  • "Field123@Test" → "field123_test" + *
  • "123field" → "field_123field" + *
+ * + * @param fieldName the original field name to sanitize + * @return sanitized field name compatible with Solr requirements, or "field" if input is + * null/empty + * @see Solr + * Field Guide + */ + public static String sanitizeFieldName(String fieldName) { + + // Convert to lowercase and replace invalid characters with underscores + String sanitized = + INVALID_CHARACTERS_PATTERN.matcher(fieldName.toLowerCase()).replaceAll("_"); + + // Remove leading/trailing underscores and collapse multiple underscores + sanitized = LEADING_TRAILING_UNDERSCORES_PATTERN.matcher(sanitized).replaceAll(""); + sanitized = MULTIPLE_UNDERSCORES_PATTERN.matcher(sanitized).replaceAll("_"); + + // If the result is empty after sanitization, provide a default name + if (sanitized.isEmpty()) { + return "field"; + } + + // Ensure the field name doesn't start with a number (Solr requirement) + if (Character.isDigit(sanitized.charAt(0))) { + sanitized = "field_" + sanitized; + } + + return sanitized; + } +} diff --git a/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/IndexingDocumentCreator.java b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/IndexingDocumentCreator.java new file mode 100644 index 0000000..ce999da --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/IndexingDocumentCreator.java @@ -0,0 +1,115 @@ +package org.apache.solr.mcp.server.indexing.documentcreator; + +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.mcp.server.indexing.IndexingService; +import org.springframework.stereotype.Service; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * Spring Service responsible for creating SolrInputDocument objects from various data formats. + * + *

This service handles the conversion of JSON, CSV, and XML documents into Solr-compatible + * format using a schema-less approach where Solr automatically detects field types, eliminating the + * need for predefined schema configuration. + * + *

Core Features: + * + *

    + *
  • Schema-less Document Creation: Automatic field type detection by Solr + *
  • JSON Processing: Support for complex nested JSON documents + *
  • CSV Processing: Support for comma-separated value files with headers + *
  • XML Processing: Support for XML documents with element flattening and + * attribute handling + *
  • Field Sanitization: Automatic cleanup of field names for Solr + * compatibility + *
+ * + * @author adityamparikh + * @version 0.0.1 + * @see SolrInputDocument + * @see IndexingService + * @since 0.0.1 + */ +@Service +public class IndexingDocumentCreator { + + private static final int MAX_XML_SIZE_BYTES = 10 * 1024 * 1024; // 10MB limit + + private final XmlDocumentCreator xmlDocumentCreator; + + private final CsvDocumentCreator csvDocumentCreator; + + private final JsonDocumentCreator jsonDocumentCreator; + + public IndexingDocumentCreator( + XmlDocumentCreator xmlDocumentCreator, + CsvDocumentCreator csvDocumentCreator, + JsonDocumentCreator jsonDocumentCreator) { + this.xmlDocumentCreator = xmlDocumentCreator; + this.csvDocumentCreator = csvDocumentCreator; + this.jsonDocumentCreator = jsonDocumentCreator; + } + + /** + * Creates a list of schema-less SolrInputDocument objects from a JSON string. + * + *

This method delegates JSON processing to the JsonDocumentProcessor utility class. + * + * @param json JSON string containing document data (must be an array) + * @return list of SolrInputDocument objects ready for indexing + * @throws DocumentProcessingException if JSON parsing fails or the structure is invalid + * @see JsonDocumentCreator + */ + public List createSchemalessDocumentsFromJson(String json) + throws DocumentProcessingException { + return jsonDocumentCreator.create(json); + } + + /** + * Creates a list of schema-less SolrInputDocument objects from a CSV string. + * + *

This method delegates CSV processing to the CsvDocumentProcessor utility class. + * + * @param csv CSV string containing document data (first row must be headers) + * @return list of SolrInputDocument objects ready for indexing + * @throws DocumentProcessingException if CSV parsing fails or the structure is invalid + * @see CsvDocumentCreator + */ + public List createSchemalessDocumentsFromCsv(String csv) + throws DocumentProcessingException { + return csvDocumentCreator.create(csv); + } + + /** + * Creates a list of schema-less SolrInputDocument objects from an XML string. + * + *

This method delegates XML processing to the XmlDocumentProcessor utility class. + * + * @param xml XML string containing document data + * @return list of SolrInputDocument objects ready for indexing + * @throws DocumentProcessingException if XML parser configuration fails + * @see XmlDocumentCreator + */ + public List createSchemalessDocumentsFromXml(String xml) + throws DocumentProcessingException { + + // Input validation + if (xml == null || xml.trim().isEmpty()) { + throw new IllegalArgumentException("XML input cannot be null or empty"); + } + + byte[] xmlBytes = xml.getBytes(StandardCharsets.UTF_8); + if (xmlBytes.length > MAX_XML_SIZE_BYTES) { + throw new IllegalArgumentException( + "XML document too large: " + + xmlBytes.length + + " bytes (max: " + + MAX_XML_SIZE_BYTES + + ")"); + } + + return xmlDocumentCreator.create(xml); + } +} diff --git a/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/JsonDocumentCreator.java b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/JsonDocumentCreator.java new file mode 100644 index 0000000..fa4777c --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/JsonDocumentCreator.java @@ -0,0 +1,204 @@ +package org.apache.solr.mcp.server.indexing.documentcreator; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.solr.common.SolrInputDocument; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Utility class for processing JSON documents and converting them to SolrInputDocument objects. + * + *

This class handles the conversion of JSON documents into Solr-compatible format using a + * schema-less approach where Solr automatically detects field types. + */ +@Component +public class JsonDocumentCreator implements SolrDocumentCreator { + + private static final int MAX_INPUT_SIZE_BYTES = 10 * 1024 * 1024; + + /** + * Creates a list of schema-less SolrInputDocument objects from a JSON string. + * + *

This method implements a flexible document conversion strategy that allows Solr to + * automatically detect field types without requiring predefined schema configuration. It + * processes complex JSON structures by flattening nested objects and handling arrays + * appropriately for Solr's multi-valued field support. + * + *

Schema-less Benefits: + * + *

    + *
  • Flexibility: No need to predefine field types in schema + *
  • Rapid Prototyping: Quick iteration on document structures + *
  • Type Detection: Solr automatically infers optimal field types + *
  • Dynamic Fields: Support for varying document structures + *
+ * + *

JSON Processing Rules: + * + *

    + *
  • Nested Objects: Flattened using underscore notation (e.g., "user.name" + * → "user_name") + *
  • Arrays: Non-object arrays converted to multi-valued fields + *
  • Null Values: Ignored and not indexed + *
  • Object Arrays: Skipped to avoid complex nested structures + *
+ * + *

Field Name Sanitization: + * + *

Field names are automatically sanitized to ensure Solr compatibility by removing special + * characters and converting to lowercase with underscore separators. + * + *

Example Transformations: + * + *

{@code
+     * Input:  {"user":{"name":"John","age":30},"tags":["tech","java"]}
+     * Output: {user_name:"John", user_age:30, tags:["tech","java"]}
+     * }
+ * + * @param json JSON string containing document data (must be an array) + * @return list of SolrInputDocument objects ready for indexing + * @throws DocumentProcessingException if JSON parsing fails, input validation fails, or the + * structure is invalid + * @see SolrInputDocument + * @see #addAllFieldsFlat(SolrInputDocument, JsonNode, String) + * @see FieldNameSanitizer#sanitizeFieldName(String) + */ + public List create(String json) throws DocumentProcessingException { + if (json.getBytes(StandardCharsets.UTF_8).length > MAX_INPUT_SIZE_BYTES) { + throw new DocumentProcessingException( + "Input too large: exceeds maximum size of " + MAX_INPUT_SIZE_BYTES + " bytes"); + } + + List documents = new ArrayList<>(); + + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode rootNode = mapper.readTree(json); + + if (rootNode.isArray()) { + for (JsonNode item : rootNode) { + SolrInputDocument doc = new SolrInputDocument(); + + // Add all fields without type suffixes - let Solr figure it out + addAllFieldsFlat(doc, item, ""); + documents.add(doc); + } + } + } catch (IOException e) { + throw new DocumentProcessingException("Failed to parse JSON document", e); + } + + return documents; + } + + /** + * Recursively flattens JSON nodes and adds them as fields to a SolrInputDocument. + * + *

This method implements the core logic for converting nested JSON structures into flat + * field names that Solr can efficiently index and search. It handles various JSON node types + * appropriately while maintaining data integrity. + * + *

Processing Logic: + * + *

    + *
  • Null Values: Skipped to avoid indexing empty fields + *
  • Arrays: Non-object items converted to multi-valued fields + *
  • Objects: Recursively flattened with prefix concatenation + *
  • Primitives: Directly added with appropriate type conversion + *
+ * + * @param doc the SolrInputDocument to add fields to + * @param node the JSON node to process + * @param prefix current field name prefix for nested object flattening + * @see #convertJsonValue(JsonNode) + * @see FieldNameSanitizer#sanitizeFieldName(String) + */ + private void addAllFieldsFlat(SolrInputDocument doc, JsonNode node, String prefix) { + Set> fields = node.properties(); + fields.forEach( + field -> + processFieldValue( + doc, + field.getValue(), + FieldNameSanitizer.sanitizeFieldName(prefix + field.getKey()))); + } + + /** + * Processes the provided field value and adds it to the given SolrInputDocument. Handles cases + * where the field value is an array, object, or a simple value. + * + * @param doc the SolrInputDocument to which the field value will be added + * @param value the JsonNode representing the field value to be processed + * @param fieldName the name of the field to be added to the SolrInputDocument + */ + private void processFieldValue(SolrInputDocument doc, JsonNode value, String fieldName) { + if (value.isNull()) { + return; + } + + if (value.isArray()) { + processArrayField(doc, value, fieldName); + } else if (value.isObject()) { + addAllFieldsFlat(doc, value, fieldName + "_"); + } else { + doc.addField(fieldName, convertJsonValue(value)); + } + } + + /** + * Processes a JSON array field and adds its non-object elements to the specified field in the + * given SolrInputDocument. + * + * @param doc the SolrInputDocument to which the processed field will be added + * @param arrayValue the JSON array node to process + * @param fieldName the name of the field in the SolrInputDocument to which the array values + * will be added + */ + private void processArrayField(SolrInputDocument doc, JsonNode arrayValue, String fieldName) { + List values = new ArrayList<>(); + for (JsonNode item : arrayValue) { + if (!item.isObject()) { + values.add(convertJsonValue(item)); + } + } + if (!values.isEmpty()) { + doc.addField(fieldName, values); + } + } + + /** + * Converts a JsonNode value to the appropriate Java object type for Solr indexing. + * + *

This method provides type-aware conversion of JSON values to their corresponding Java + * types, ensuring that Solr receives properly typed data for optimal field type detection and + * indexing performance. + * + *

Supported Type Conversions: + * + *

    + *
  • Boolean: JSON boolean → Java Boolean + *
  • Integer: JSON number (int range) → Java Integer + *
  • Long: JSON number (long range) → Java Long + *
  • Double: JSON number (decimal) → Java Double + *
  • String: All other values → Java String + *
+ * + * @param value the JsonNode value to convert + * @return the converted Java object with appropriate type + * @see JsonNode + */ + private Object convertJsonValue(JsonNode value) { + if (value.isBoolean()) return value.asBoolean(); + if (value.isLong()) return value.asLong(); + if (value.isDouble()) return value.asDouble(); + if (value.isInt()) return value.asInt(); + return value.asText(); + } +} diff --git a/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/SolrDocumentCreator.java b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/SolrDocumentCreator.java new file mode 100644 index 0000000..288a0fa --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/SolrDocumentCreator.java @@ -0,0 +1,86 @@ +package org.apache.solr.mcp.server.indexing.documentcreator; + +import org.apache.solr.common.SolrInputDocument; + +import java.util.List; + +/** + * Interface defining the contract for creating SolrInputDocument objects from various data formats. + * + *

This interface provides a unified abstraction for converting different document formats (JSON, + * CSV, XML, etc.) into Solr-compatible SolrInputDocument objects. Implementations handle + * format-specific parsing and field sanitization to ensure proper Solr indexing. + * + *

Design Principles: + * + *

    + *
  • Format Agnostic: Common interface for all document types + *
  • Schema-less Processing: Supports dynamic field creation without predefined + * schema + *
  • Error Handling: Consistent exception handling across implementations + *
  • Field Sanitization: Automatic cleanup of field names for Solr + * compatibility + *
+ * + *

Implementation Guidelines: + * + *

    + *
  • Handle null or empty input gracefully + *
  • Sanitize field names using {@link FieldNameSanitizer} + *
  • Preserve original data types where possible + *
  • Throw {@link DocumentProcessingException} for processing errors + *
+ * + *

Usage Example: + * + *

{@code
+ * SolrDocumentCreator creator = new JsonDocumentCreator();
+ * String jsonData = "[{\"title\":\"Document 1\",\"content\":\"Content here\"}]";
+ * List documents = creator.create(jsonData);
+ * }
+ * + * @author adityamparikh + * @version 0.0.1 + * @see SolrInputDocument + * @see DocumentProcessingException + * @see FieldNameSanitizer + * @since 0.0.1 + */ +public interface SolrDocumentCreator { + + /** + * Creates a list of SolrInputDocument objects from the provided content string. + * + *

This method parses the input content according to the specific format handled by the + * implementing class (JSON, CSV, XML, etc.) and converts it into a list of SolrInputDocument + * objects ready for indexing. + * + *

Processing Behavior: + * + *

    + *
  • Field Sanitization: All field names are sanitized for Solr + * compatibility + *
  • Type Preservation: Original data types are maintained where possible + *
  • Multiple Documents: Single content string may produce multiple + * documents + *
  • Error Handling: Invalid content results in DocumentProcessingException + *
+ * + *

Input Validation: + * + *

    + *
  • Null input should be handled gracefully (implementation-dependent) + *
  • Empty input should return empty list + *
  • Malformed content should throw DocumentProcessingException + *
+ * + * @param content the content string to be parsed and converted to SolrInputDocument objects. + * The format depends on the implementing class (JSON array, CSV data, XML, etc.) + * @return a list of SolrInputDocument objects created from the parsed content. Returns empty + * list if content is empty or contains no valid documents + * @throws DocumentProcessingException if the content cannot be parsed or converted due to + * format errors, invalid structure, or processing failures + * @throws IllegalArgumentException if content is null (implementation-dependent) + */ + List create(String content) throws DocumentProcessingException; +} diff --git a/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/XmlDocumentCreator.java b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/XmlDocumentCreator.java new file mode 100644 index 0000000..55cb751 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/XmlDocumentCreator.java @@ -0,0 +1,274 @@ +package org.apache.solr.mcp.server.indexing.documentcreator; + +import org.apache.solr.common.SolrInputDocument; +import org.springframework.stereotype.Component; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Utility class for processing XML documents and converting them to SolrInputDocument objects. + * + *

This class handles the conversion of XML documents into Solr-compatible format using a + * schema-less approach where Solr automatically detects field types. + */ +@Component +public class XmlDocumentCreator implements SolrDocumentCreator { + + /** + * Creates a list of SolrInputDocument objects from XML content. + * + *

This method parses the XML and creates documents based on the structure: - If the XML has + * multiple child elements with the same tag name (indicating repeated structures), each child + * element becomes a separate document - Otherwise, the entire XML structure is treated as a + * single document + * + *

This approach is flexible and doesn't rely on hardcoded element names, allowing it to work + * with any XML structure. + * + * @param xml the XML content to process + * @return list of SolrInputDocument objects ready for indexing + * @throws DocumentProcessingException if XML parsing fails, parser configuration fails, or + * structural errors occur + */ + public List create(String xml) throws DocumentProcessingException { + try { + Element rootElement = parseXmlDocument(xml); + return processRootElement(rootElement); + } catch (ParserConfigurationException e) { + throw new DocumentProcessingException("Failed to configure XML parser", e); + } catch (SAXException e) { + throw new DocumentProcessingException( + "Failed to parse XML document: structural error", e); + } catch (IOException e) { + throw new DocumentProcessingException("Failed to read XML document", e); + } + } + + /** + * Parses XML string into a DOM Element. + */ + private Element parseXmlDocument(String xml) + throws ParserConfigurationException, SAXException, IOException { + DocumentBuilderFactory factory = createSecureDocumentBuilderFactory(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = + builder.parse(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))); + return doc.getDocumentElement(); + } + + /** + * Creates a secure DocumentBuilderFactory with XXE protection. + */ + private DocumentBuilderFactory createSecureDocumentBuilderFactory() + throws ParserConfigurationException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + factory.setFeature("http://xml.org/sax/features/external-general-entities", false); + factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + factory.setXIncludeAware(false); + factory.setExpandEntityReferences(false); + return factory; + } + + /** Processes the root element and determines document structure strategy. */ + private List processRootElement(Element rootElement) { + List childElements = extractChildElements(rootElement); + + if (shouldTreatChildrenAsDocuments(childElements)) { + return createDocumentsFromChildren(childElements); + } else { + return createSingleDocument(rootElement); + } + } + + /** Extracts child elements from the root element. */ + private List extractChildElements(Element rootElement) { + NodeList children = rootElement.getChildNodes(); + List childElements = new ArrayList<>(); + + for (int i = 0; i < children.getLength(); i++) { + if (children.item(i).getNodeType() == Node.ELEMENT_NODE) { + childElements.add((Element) children.item(i)); + } + } + + return childElements; + } + + /** Determines if child elements should be treated as separate documents. */ + private boolean shouldTreatChildrenAsDocuments(List childElements) { + Map childElementCounts = new HashMap<>(); + + for (Element child : childElements) { + String tagName = child.getTagName(); + childElementCounts.put(tagName, childElementCounts.getOrDefault(tagName, 0) + 1); + } + + return childElementCounts.values().stream().anyMatch(count -> count > 1); + } + + /** Creates documents from child elements (multiple documents strategy). */ + private List createDocumentsFromChildren(List childElements) { + List documents = new ArrayList<>(); + + for (Element childElement : childElements) { + SolrInputDocument solrDoc = new SolrInputDocument(); + addXmlElementFields(solrDoc, childElement, ""); + if (!solrDoc.isEmpty()) { + documents.add(solrDoc); + } + } + + return documents; + } + + /** Creates a single document from the root element. */ + private List createSingleDocument(Element rootElement) { + List documents = new ArrayList<>(); + SolrInputDocument solrDoc = new SolrInputDocument(); + addXmlElementFields(solrDoc, rootElement, ""); + + if (!solrDoc.isEmpty()) { + documents.add(solrDoc); + } + + return documents; + } + + /** + * Recursively processes XML elements and adds them as fields to a SolrInputDocument. + * + *

This method implements the core logic for converting nested XML structures into flat field + * names that Solr can efficiently index and search. It handles both element content and + * attributes while maintaining data integrity. + * + *

Processing Logic: + * + *

    + *
  • Attributes: Converted to fields with "_attr" suffix + *
  • Text Content: Element text content indexed directly + *
  • Child Elements: Recursively processed with prefix concatenation + *
  • Empty Elements: Skipped to avoid indexing empty fields + *
  • Repeated Elements: Combined into multi-valued fields + *
+ * + *

Field Naming Convention: + * + *

    + *
  • Nested elements: parent_child (e.g., author_name) + *
  • Attributes: elementname_attr (e.g., id_attr) + *
  • All field names are sanitized for Solr compatibility + *
+ * + * @param doc the SolrInputDocument to add fields to + * @param element the XML element to process + * @param prefix current field name prefix for nested element flattening + * @see FieldNameSanitizer#sanitizeFieldName(String) + */ + private void addXmlElementFields(SolrInputDocument doc, Element element, String prefix) { + String elementName = FieldNameSanitizer.sanitizeFieldName(element.getTagName()); + String currentPrefix = prefix.isEmpty() ? elementName : prefix + "_" + elementName; + + processXmlAttributes(doc, element, prefix, currentPrefix); + + NodeList children = element.getChildNodes(); + boolean hasChildElements = hasChildElements(children); + + processXmlTextContent(doc, elementName, currentPrefix, prefix, hasChildElements, children); + processXmlChildElements(doc, children, currentPrefix); + } + + /** + * Processes XML element attributes and adds them as fields to the document. + */ + private void processXmlAttributes( + SolrInputDocument doc, Element element, String prefix, String currentPrefix) { + if (!element.hasAttributes()) { + return; + } + + for (int i = 0; i < element.getAttributes().getLength(); i++) { + Node attr = element.getAttributes().item(i); + String attrName = FieldNameSanitizer.sanitizeFieldName(attr.getNodeName()) + "_attr"; + String fieldName = prefix.isEmpty() ? attrName : currentPrefix + "_" + attrName; + String attrValue = attr.getNodeValue(); + + if (attrValue != null && !attrValue.trim().isEmpty()) { + doc.addField(fieldName, attrValue.trim()); + } + } + } + + /** Checks if the node list contains any child elements. */ + private boolean hasChildElements(NodeList children) { + for (int i = 0; i < children.getLength(); i++) { + if (children.item(i).getNodeType() == Node.ELEMENT_NODE) { + return true; + } + } + return false; + } + + /** + * Processes XML text content and adds it as a field to the document. + */ + private void processXmlTextContent( + SolrInputDocument doc, + String elementName, + String currentPrefix, + String prefix, + boolean hasChildElements, + NodeList children) { + String textContent = extractTextContent(children); + if (!textContent.isEmpty()) { + String fieldName = prefix.isEmpty() ? elementName : currentPrefix; + doc.addField(fieldName, textContent); + } + } + + /** Extracts text content from child nodes. */ + private String extractTextContent(NodeList children) { + StringBuilder textContent = new StringBuilder(); + + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.TEXT_NODE) { + String text = child.getNodeValue(); + if (text != null && !text.trim().isEmpty()) { + textContent.append(text.trim()).append(" "); + } + } + } + + return textContent.toString().trim(); + } + + /** + * Recursively processes XML child elements. + */ + private void processXmlChildElements( + SolrInputDocument doc, NodeList children, String currentPrefix) { + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE) { + addXmlElementFields(doc, (Element) child, currentPrefix); + } + } + } +} diff --git a/src/main/java/org/apache/solr/mcp/server/metadata/CollectionService.java b/src/main/java/org/apache/solr/mcp/server/metadata/CollectionService.java new file mode 100644 index 0000000..c59e7de --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/metadata/CollectionService.java @@ -0,0 +1,921 @@ +package org.apache.solr.mcp.server.metadata; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrRequest; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.impl.CloudSolrClient; +import org.apache.solr.client.solrj.request.CollectionAdminRequest; +import org.apache.solr.client.solrj.request.CoreAdminRequest; +import org.apache.solr.client.solrj.request.GenericSolrRequest; +import org.apache.solr.client.solrj.request.LukeRequest; +import org.apache.solr.client.solrj.response.*; +import org.apache.solr.common.params.CoreAdminParams; +import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.mcp.server.config.SolrConfigurationProperties; +import org.springaicommunity.mcp.annotation.McpTool; +import org.springaicommunity.mcp.annotation.McpToolParam; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.apache.solr.mcp.server.metadata.CollectionUtils.*; + +/** + * Spring Service providing comprehensive Solr collection management and monitoring capabilities for + * Model Context Protocol (MCP) clients. + * + *

This service acts as the primary interface for collection-level operations in the Solr MCP + * Server, providing tools for collection discovery, metrics gathering, health monitoring, and + * performance analysis. It bridges the gap between MCP clients (like Claude Desktop) and Apache + * Solr through the SolrJ client library. + * + *

Core Capabilities: + * + *

    + *
  • Collection Discovery: Lists available collections/cores with automatic + * SolrCloud vs standalone detection + *
  • Performance Monitoring: Comprehensive metrics collection including index, + * query, cache, and handler statistics + *
  • Health Monitoring: Real-time health checks with availability and + * performance indicators + *
  • Shard-Aware Operations: Intelligent handling of SolrCloud shard names and + * collection name extraction + *
+ * + *

Implementation Details: + * + *

This class uses extensively documented constants for all API parameters, field names, and + * paths to ensure maintainability and reduce the risk of typos. All string literals have been + * replaced with well-named constants that are organized by category (API parameters, response + * parsing keys, handler paths, statistics fields, etc.). + * + *

MCP Tool Integration: + * + *

Methods annotated with {@code @McpTool} are automatically exposed as MCP tools that can be + * invoked by AI clients. These tools provide natural language interfaces to Solr operations. + * + *

Supported Solr Deployments: + * + *

    + *
  • SolrCloud: Distributed mode using Collections API + *
  • Standalone: Single-node mode using Core Admin API + *
+ * + *

Error Handling: + * + *

The service implements robust error handling with graceful degradation. Failed operations + * return null values rather than throwing exceptions (except where validation requires it), + * allowing partial metrics collection when some endpoints are unavailable. + * + *

Example Usage: + * + *

{@code
+ * // List all available collections
+ * List collections = collectionService.listCollections();
+ *
+ * // Get comprehensive metrics for a collection
+ * SolrMetrics metrics = collectionService.getCollectionStats("my_collection");
+ *
+ * // Check collection health
+ * SolrHealthStatus health = collectionService.checkHealth("my_collection");
+ * }
+ * + * @author adityamparikh + * @version 0.0.1 + * @see SolrMetrics + * @see SolrHealthStatus + * @see org.apache.solr.client.solrj.SolrClient + * @since 0.0.1 + */ +@Service +public class CollectionService { + + // ======================================== + // Constants for API Parameters and Paths + // ======================================== + + /** + * Category parameter value for cache-related MBeans requests + */ + private static final String CACHE_CATEGORY = "CACHE"; + + /** Category parameter value for query handler MBeans requests */ + private static final String QUERY_HANDLER_CATEGORY = "QUERYHANDLER"; + + /** Combined category parameter value for both query and update handler MBeans requests */ + private static final String HANDLER_CATEGORIES = "QUERYHANDLER,UPDATEHANDLER"; + + /** Universal Solr query pattern to match all documents in a collection */ + private static final String ALL_DOCUMENTS_QUERY = "*:*"; + + /** Suffix pattern used to identify shard names in SolrCloud deployments */ + private static final String SHARD_SUFFIX = "_shard"; + + /** Request parameter name for enabling statistics in MBeans requests */ + private static final String STATS_PARAM = "stats"; + + /** Request parameter name for specifying category filters in MBeans requests */ + private static final String CAT_PARAM = "cat"; + + /** Request parameter name for specifying response writer type */ + private static final String WT_PARAM = "wt"; + + /** JSON format specification for response writer type */ + private static final String JSON_FORMAT = "json"; + + // ======================================== + // Constants for Response Parsing + // ======================================== + + /** Key name for collections list in Collections API responses */ + private static final String COLLECTIONS_KEY = "collections"; + + /** Key name for segment count information in Luke response */ + private static final String SEGMENT_COUNT_KEY = "segmentCount"; + + /** Key name for query result cache in MBeans cache responses */ + private static final String QUERY_RESULT_CACHE_KEY = "queryResultCache"; + + /** Key name for document cache in MBeans cache responses */ + private static final String DOCUMENT_CACHE_KEY = "documentCache"; + + /** Key name for filter cache in MBeans cache responses */ + private static final String FILTER_CACHE_KEY = "filterCache"; + + /** Key name for statistics section in MBeans responses */ + private static final String STATS_KEY = "stats"; + + // ======================================== + // Constants for Handler Paths + // ======================================== + + /** URL path for Solr select (query) handler */ + private static final String SELECT_HANDLER_PATH = "/select"; + + /** URL path for Solr update handler */ + private static final String UPDATE_HANDLER_PATH = "/update"; + + /** URL path for Solr MBeans admin endpoint */ + private static final String ADMIN_MBEANS_PATH = "/admin/mbeans"; + + /** URL path separator character */ + private static final String PATH_SEPARATOR = "/"; + + // ======================================== + // Constants for Statistics Field Names + // ======================================== + + /** Field name for cache/handler lookup count statistics */ + private static final String LOOKUPS_FIELD = "lookups"; + + /** Field name for cache hit count statistics */ + private static final String HITS_FIELD = "hits"; + + /** Field name for cache hit ratio statistics */ + private static final String HITRATIO_FIELD = "hitratio"; + + /** Field name for cache insert count statistics */ + private static final String INSERTS_FIELD = "inserts"; + + /** Field name for cache eviction count statistics */ + private static final String EVICTIONS_FIELD = "evictions"; + + /** Field name for cache size statistics */ + private static final String SIZE_FIELD = "size"; + + /** Field name for handler request count statistics */ + private static final String REQUESTS_FIELD = "requests"; + + /** Field name for handler error count statistics */ + private static final String ERRORS_FIELD = "errors"; + + /** Field name for handler timeout count statistics */ + private static final String TIMEOUTS_FIELD = "timeouts"; + + /** Field name for handler total processing time statistics */ + private static final String TOTAL_TIME_FIELD = "totalTime"; + + /** Field name for handler average time per request statistics */ + private static final String AVG_TIME_PER_REQUEST_FIELD = "avgTimePerRequest"; + + /** Field name for handler average requests per second statistics */ + private static final String AVG_REQUESTS_PER_SECOND_FIELD = "avgRequestsPerSecond"; + + // ======================================== + // Constants for Error Messages + // ======================================== + + /** Error message prefix for collection not found exceptions */ + private static final String COLLECTION_NOT_FOUND_ERROR = "Collection not found: "; + + /** SolrJ client for communicating with Solr server */ + private final SolrClient solrClient; + + /** + * Constructs a new CollectionService with the required dependencies. + * + *

This constructor is automatically called by Spring's dependency injection framework during + * application startup. + * + * @param solrClient the SolrJ client instance for communicating with Solr + * @see SolrClient + * @see SolrConfigurationProperties + */ + public CollectionService(SolrClient solrClient) { + this.solrClient = solrClient; + } + + /** + * Lists all available Solr collections or cores in the cluster. + * + *

This method automatically detects the Solr deployment type and uses the appropriate API: + * + *

    + *
  • SolrCloud: Uses Collections API to list distributed collections + *
  • Standalone: Uses Core Admin API to list individual cores + *
+ * + *

In SolrCloud environments, the returned names may include shard identifiers (e.g., + * "films_shard1_replica_n1"). Use {@link #extractCollectionName(String)} to get the base + * collection name if needed. + * + *

Error Handling: + * + *

If the operation fails due to connectivity issues or API errors, an empty list is returned + * rather than throwing an exception, allowing the application to continue functioning with + * degraded capabilities. + * + *

MCP Tool Usage: + * + *

This method is exposed as an MCP tool and can be invoked by AI clients with natural + * language requests like "list all collections" or "show me available databases". + * + * @return a list of collection/core names, or an empty list if unable to retrieve them + * @see CollectionAdminRequest.List + * @see CoreAdminRequest + */ + @McpTool(description = "List solr collections") + public List listCollections() { + try { + if (solrClient instanceof CloudSolrClient) { + // For SolrCloud - use Collections API + CollectionAdminRequest.List request = new CollectionAdminRequest.List(); + CollectionAdminResponse response = request.process(solrClient); + + @SuppressWarnings("unchecked") + List collections = + (List) response.getResponse().get(COLLECTIONS_KEY); + return collections != null ? collections : new ArrayList<>(); + } else { + // For standalone Solr - use Core Admin API + CoreAdminRequest coreAdminRequest = new CoreAdminRequest(); + coreAdminRequest.setAction(CoreAdminParams.CoreAdminAction.STATUS); + CoreAdminResponse coreResponse = coreAdminRequest.process(solrClient); + + List cores = new ArrayList<>(); + NamedList> coreStatus = coreResponse.getCoreStatus(); + for (int i = 0; i < coreStatus.size(); i++) { + cores.add(coreStatus.getName(i)); + } + return cores; + } + } catch (SolrServerException | IOException _) { + return new ArrayList<>(); + } + } + + /** + * Retrieves comprehensive performance metrics and statistics for a specified Solr collection. + * + *

This method aggregates metrics from multiple Solr endpoints to provide a complete + * performance profile including index health, query performance, cache utilization, and request + * handler statistics. + * + *

Collected Metrics: + * + *

    + *
  • Index Statistics: Document counts, segment information (via Luke + * handler) + *
  • Query Performance: Response times, result counts, relevance scores + *
  • Cache Utilization: Hit ratios, eviction rates for all cache types + *
  • Handler Performance: Request volumes, error rates, throughput metrics + *
+ * + *

Collection Name Handling: + * + *

Supports both collection names and shard names. If a shard name like + * "films_shard1_replica_n1" is provided, it will be automatically converted to the base + * collection name "films" for API calls. + * + *

Validation: + * + *

The method validates that the specified collection exists before attempting to collect + * metrics. If the collection is not found, an {@code IllegalArgumentException} is thrown with a + * descriptive error message. + * + *

MCP Tool Usage: + * + *

Exposed as an MCP tool for natural language queries like "get metrics for my_collection" + * or "show me performance stats for the search index". + * + * @param collection the name of the collection to analyze (supports both collection and shard + * names) + * @return comprehensive metrics object containing all collected statistics + * @throws IllegalArgumentException if the specified collection does not exist + * @throws SolrServerException if there are errors communicating with Solr + * @throws IOException if there are I/O errors during communication + * @see SolrMetrics + * @see LukeRequest + * @see #extractCollectionName(String) + */ + @McpTool(description = "Get stats/metrics on a Solr collection") + public SolrMetrics getCollectionStats( + @McpToolParam(description = "Solr collection to get stats/metrics for") + String collection) + throws SolrServerException, IOException { + // Extract actual collection name from shard name if needed + String actualCollection = extractCollectionName(collection); + + // Validate collection exists + if (!validateCollectionExists(actualCollection)) { + throw new IllegalArgumentException(COLLECTION_NOT_FOUND_ERROR + actualCollection); + } + + // Index statistics using Luke + LukeRequest lukeRequest = new LukeRequest(); + lukeRequest.setIncludeIndexFieldFlags(true); + LukeResponse lukeResponse = lukeRequest.process(solrClient, actualCollection); + + // Query performance metrics + QueryResponse statsResponse = + solrClient.query(actualCollection, new SolrQuery(ALL_DOCUMENTS_QUERY).setRows(0)); + + return new SolrMetrics( + buildIndexStats(lukeResponse), + buildQueryStats(statsResponse), + getCacheMetrics(actualCollection), + getHandlerMetrics(actualCollection), + new Date()); + } + + /** + * Builds an IndexStats object from a Solr Luke response containing index metadata. + * + *

The Luke handler provides low-level Lucene index information including document counts, + * segment details, and field statistics. This method extracts the essential index health + * metrics for monitoring and analysis. + * + *

Extracted Metrics: + * + *

    + *
  • numDocs: Total number of documents excluding deleted ones + *
  • segmentCount: Number of Lucene segments (performance indicator) + *
+ * + *

Performance Implications: + * + *

High segment counts may indicate the need for index optimization to improve search + * performance. The optimal segment count depends on index size and update frequency. + * + * @param lukeResponse the Luke response containing raw index information + * @return IndexStats object with extracted and formatted metrics + * @see IndexStats + * @see LukeResponse + */ + public IndexStats buildIndexStats(LukeResponse lukeResponse) { + NamedList indexInfo = lukeResponse.getIndexInfo(); + + // Extract index information using helper methods + Integer segmentCount = getInteger(indexInfo, SEGMENT_COUNT_KEY); + + return new IndexStats(lukeResponse.getNumDocs(), segmentCount); + } + + /** + * Builds a QueryStats object from a Solr query response containing performance metrics. + * + *

Extracts key performance indicators from a query execution including timing, result + * characteristics, and relevance scoring information. These metrics help identify query + * performance patterns and optimization opportunities. + * + *

Extracted Metrics: + * + *

    + *
  • queryTime: Execution time in milliseconds + *
  • totalResults: Total matching documents found + *
  • start: Pagination offset (0-based) + *
  • maxScore: Highest relevance score in results + *
+ * + *

Performance Analysis: + * + *

Query time metrics help identify slow queries that may need optimization, while result + * counts and scores provide insight into search effectiveness. + * + * @param response the query response containing performance and result metadata + * @return QueryStats object with extracted performance metrics + * @see QueryStats + * @see QueryResponse + */ + public QueryStats buildQueryStats(QueryResponse response) { + + return new QueryStats( + response.getQTime(), + response.getResults().getNumFound(), + response.getResults().getStart(), + response.getResults().getMaxScore()); + } + + /** + * Retrieves cache performance metrics for all cache types in a Solr collection. + * + *

Collects detailed cache utilization statistics from Solr's MBeans endpoint, providing + * insights into cache effectiveness and memory usage patterns. Cache performance directly + * impacts query response times and system efficiency. + * + *

Monitored Cache Types: + * + *

    + *
  • Query Result Cache: Caches complete query results for identical + * searches + *
  • Document Cache: Caches retrieved document field data + *
  • Filter Cache: Caches filter query results for faceting and filtering + *
+ * + *

Key Performance Indicators: + * + *

    + *
  • Hit Ratio: Cache effectiveness (higher is better) + *
  • Evictions: Memory pressure indicator + *
  • Size: Current cache utilization + *
+ * + *

Error Handling: + * + *

Returns {@code null} if cache statistics cannot be retrieved or if all cache types are + * empty/unavailable. This allows graceful degradation when cache monitoring is not available. + * + * @param collection the collection name to retrieve cache metrics for + * @return CacheStats object with all cache performance metrics, or null if unavailable + * @see CacheStats + * @see CacheInfo + * @see #extractCacheStats(NamedList) + * @see #isCacheStatsEmpty(CacheStats) + */ + public CacheStats getCacheMetrics(String collection) { + try { + // Get MBeans for cache information + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set(STATS_PARAM, "true"); + params.set(CAT_PARAM, CACHE_CATEGORY); + params.set(WT_PARAM, JSON_FORMAT); + + // Extract actual collection name from shard name if needed + String actualCollection = extractCollectionName(collection); + + // Validate collection exists first + if (!validateCollectionExists(actualCollection)) { + return null; // Return null instead of empty object + } + + String path = PATH_SEPARATOR + actualCollection + ADMIN_MBEANS_PATH; + + GenericSolrRequest request = + new GenericSolrRequest(SolrRequest.METHOD.GET, path, params); + + NamedList response = solrClient.request(request); + CacheStats stats = extractCacheStats(response); + + // Return null if all cache stats are empty/null + if (isCacheStatsEmpty(stats)) { + return null; + } + + return stats; + } catch (SolrServerException | IOException _) { + return null; // Return null instead of empty object + } + } + + /** + * Checks if cache statistics are empty or contain no meaningful data. + * + *

Used to determine whether cache metrics are worth returning to clients. Empty cache stats + * typically indicate that caches are not configured or not yet populated with data. + * + * @param stats the cache statistics to evaluate + * @return true if the stats are null or all cache types are null + */ + private boolean isCacheStatsEmpty(CacheStats stats) { + return stats == null + || (stats.queryResultCache() == null + && stats.documentCache() == null + && stats.filterCache() == null); + } + + /** + * Extracts cache performance statistics from Solr MBeans response data. + * + *

Parses the raw MBeans response to extract structured cache performance metrics for all + * available cache types. Each cache type provides detailed statistics including hit ratios, + * eviction rates, and current utilization. + * + *

Parsed Cache Types: + * + *

    + *
  • queryResultCache - Complete query result caching + *
  • documentCache - Retrieved document data caching + *
  • filterCache - Filter query result caching + *
+ * + *

For each cache type, the following metrics are extracted: + * + *

    + *
  • lookups, hits, hitratio - Performance effectiveness + *
  • inserts, evictions - Memory management patterns + *
  • size - Current utilization + *
+ * + * @param mbeans the raw MBeans response from Solr admin endpoint + * @return CacheStats object containing parsed metrics for all cache types + * @see CacheStats + * @see CacheInfo + */ + private CacheStats extractCacheStats(NamedList mbeans) { + CacheInfo queryResultCacheInfo = null; + CacheInfo documentCacheInfo = null; + CacheInfo filterCacheInfo = null; + + @SuppressWarnings("unchecked") + NamedList caches = (NamedList) mbeans.get(CACHE_CATEGORY); + + if (caches != null) { + // Query result cache + @SuppressWarnings("unchecked") + NamedList queryResultCache = + (NamedList) caches.get(QUERY_RESULT_CACHE_KEY); + if (queryResultCache != null) { + @SuppressWarnings("unchecked") + NamedList stats = (NamedList) queryResultCache.get(STATS_KEY); + queryResultCacheInfo = + new CacheInfo( + getLong(stats, LOOKUPS_FIELD), + getLong(stats, HITS_FIELD), + getFloat(stats, HITRATIO_FIELD), + getLong(stats, INSERTS_FIELD), + getLong(stats, EVICTIONS_FIELD), + getLong(stats, SIZE_FIELD)); + } + + // Document cache + @SuppressWarnings("unchecked") + NamedList documentCache = (NamedList) caches.get(DOCUMENT_CACHE_KEY); + if (documentCache != null) { + @SuppressWarnings("unchecked") + NamedList stats = (NamedList) documentCache.get(STATS_KEY); + documentCacheInfo = + new CacheInfo( + getLong(stats, LOOKUPS_FIELD), + getLong(stats, HITS_FIELD), + getFloat(stats, HITRATIO_FIELD), + getLong(stats, INSERTS_FIELD), + getLong(stats, EVICTIONS_FIELD), + getLong(stats, SIZE_FIELD)); + } + + // Filter cache + @SuppressWarnings("unchecked") + NamedList filterCache = (NamedList) caches.get(FILTER_CACHE_KEY); + if (filterCache != null) { + @SuppressWarnings("unchecked") + NamedList stats = (NamedList) filterCache.get(STATS_KEY); + filterCacheInfo = + new CacheInfo( + getLong(stats, LOOKUPS_FIELD), + getLong(stats, HITS_FIELD), + getFloat(stats, HITRATIO_FIELD), + getLong(stats, INSERTS_FIELD), + getLong(stats, EVICTIONS_FIELD), + getLong(stats, SIZE_FIELD)); + } + } + + return new CacheStats(queryResultCacheInfo, documentCacheInfo, filterCacheInfo); + } + + /** + * Retrieves request handler performance metrics for core Solr operations. + * + *

Collects detailed performance statistics for the primary request handlers that process + * search and update operations. Handler metrics provide insights into system throughput, error + * rates, and response time characteristics. + * + *

Monitored Handlers: + * + *

    + *
  • Select Handler ({@value #SELECT_HANDLER_PATH}): Processes search and + * query requests + *
  • Update Handler ({@value #UPDATE_HANDLER_PATH}): Processes document + * indexing operations + *
+ * + *

Performance Metrics: + * + *

    + *
  • Request Volume: Total requests processed + *
  • Error Rates: Failed request counts and timeouts + *
  • Performance: Average response times and throughput + *
+ * + *

Error Handling: + * + *

Returns {@code null} if handler statistics cannot be retrieved or if no meaningful handler + * data is available. This allows graceful degradation when handler monitoring endpoints are not + * accessible. + * + * @param collection the collection name to retrieve handler metrics for + * @return HandlerStats object with performance metrics for all handlers, or null if unavailable + * @see HandlerStats + * @see HandlerInfo + * @see #extractHandlerStats(NamedList) + * @see #isHandlerStatsEmpty(HandlerStats) + */ + public HandlerStats getHandlerMetrics(String collection) { + try { + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set(STATS_PARAM, "true"); + params.set(CAT_PARAM, HANDLER_CATEGORIES); + params.set(WT_PARAM, JSON_FORMAT); + + // Extract actual collection name from shard name if needed + String actualCollection = extractCollectionName(collection); + + // Validate collection exists first + if (!validateCollectionExists(actualCollection)) { + return null; // Return null instead of empty object + } + + String path = PATH_SEPARATOR + actualCollection + ADMIN_MBEANS_PATH; + + GenericSolrRequest request = + new GenericSolrRequest(SolrRequest.METHOD.GET, path, params); + + NamedList response = solrClient.request(request); + HandlerStats stats = extractHandlerStats(response); + + // Return null if all handler stats are empty/null + if (isHandlerStatsEmpty(stats)) { + return null; + } + + return stats; + } catch (SolrServerException | IOException _) { + return null; // Return null instead of empty object + } + } + + /** + * Checks if handler statistics are empty or contain no meaningful data. + * + *

Used to determine whether handler metrics are worth returning to clients. Empty handler + * stats typically indicate that handlers haven't processed any requests yet or statistics + * collection is not enabled. + * + * @param stats the handler statistics to evaluate + * @return true if the stats are null or all handler types are null + */ + private boolean isHandlerStatsEmpty(HandlerStats stats) { + return stats == null || (stats.selectHandler() == null && stats.updateHandler() == null); + } + + /** + * Extracts request handler performance statistics from Solr MBeans response data. + * + *

Parses the raw MBeans response to extract structured handler performance metrics for query + * and update operations. Each handler provides detailed statistics about request processing + * including volume, errors, and timing. + * + *

Parsed Handler Types: + * + *

    + *
  • /select - Search and query request handler + *
  • /update - Document indexing request handler + *
+ * + *

For each handler type, the following metrics are extracted: + * + *

    + *
  • requests, errors, timeouts - Volume and reliability + *
  • totalTime, avgTimePerRequest - Performance characteristics + *
  • avgRequestsPerSecond - Throughput capacity + *
+ * + * @param mbeans the raw MBeans response from Solr admin endpoint + * @return HandlerStats object containing parsed metrics for all handler types + * @see HandlerStats + * @see HandlerInfo + */ + private HandlerStats extractHandlerStats(NamedList mbeans) { + HandlerInfo selectHandlerInfo = null; + HandlerInfo updateHandlerInfo = null; + + @SuppressWarnings("unchecked") + NamedList queryHandlers = (NamedList) mbeans.get(QUERY_HANDLER_CATEGORY); + + if (queryHandlers != null) { + // Select handler + @SuppressWarnings("unchecked") + NamedList selectHandler = + (NamedList) queryHandlers.get(SELECT_HANDLER_PATH); + if (selectHandler != null) { + @SuppressWarnings("unchecked") + NamedList stats = (NamedList) selectHandler.get(STATS_KEY); + selectHandlerInfo = + new HandlerInfo( + getLong(stats, REQUESTS_FIELD), + getLong(stats, ERRORS_FIELD), + getLong(stats, TIMEOUTS_FIELD), + getLong(stats, TOTAL_TIME_FIELD), + getFloat(stats, AVG_TIME_PER_REQUEST_FIELD), + getFloat(stats, AVG_REQUESTS_PER_SECOND_FIELD)); + } + + // Update handler + @SuppressWarnings("unchecked") + NamedList updateHandler = + (NamedList) queryHandlers.get(UPDATE_HANDLER_PATH); + if (updateHandler != null) { + @SuppressWarnings("unchecked") + NamedList stats = (NamedList) updateHandler.get(STATS_KEY); + updateHandlerInfo = + new HandlerInfo( + getLong(stats, REQUESTS_FIELD), + getLong(stats, ERRORS_FIELD), + getLong(stats, TIMEOUTS_FIELD), + getLong(stats, TOTAL_TIME_FIELD), + getFloat(stats, AVG_TIME_PER_REQUEST_FIELD), + getFloat(stats, AVG_REQUESTS_PER_SECOND_FIELD)); + } + } + + return new HandlerStats(selectHandlerInfo, updateHandlerInfo); + } + + /** + * Extracts the actual collection name from a shard name in SolrCloud environments. + * + *

In SolrCloud deployments, collection operations often return shard names that include + * replica and shard identifiers (e.g., "films_shard1_replica_n1"). This method extracts the + * base collection name ("films") for use in API calls that require the collection name. + * + *

Extraction Logic: + * + *

    + *
  • Detects shard patterns containing the {@value #SHARD_SUFFIX} suffix + *
  • Returns the substring before the shard identifier + *
  • Returns the original string if no shard pattern is detected + *
+ * + *

Examples: + * + *

    + *
  • "films_shard1_replica_n1" → "films" + *
  • "products_shard2_replica_n3" → "products" + *
  • "simple_collection" → "simple_collection" (unchanged) + *
+ * + * @param collectionOrShard the collection or shard name to parse + * @return the extracted collection name, or the original string if no shard pattern found + */ + String extractCollectionName(String collectionOrShard) { + if (collectionOrShard == null || collectionOrShard.isEmpty()) { + return collectionOrShard; + } + + // Check if this looks like a shard name (contains "_shard" pattern) + if (collectionOrShard.contains(SHARD_SUFFIX)) { + // Extract collection name before "_shard" + int shardIndex = collectionOrShard.indexOf(SHARD_SUFFIX); + return collectionOrShard.substring(0, shardIndex); + } + + // If it doesn't look like a shard name, return as-is + return collectionOrShard; + } + + /** + * Validates that a specified collection exists in the Solr cluster. + * + *

Performs collection existence validation by checking against the list of available + * collections. Supports both exact collection name matches and shard-based matching for + * SolrCloud environments. + * + *

Validation Strategy: + * + *

    + *
  1. Exact Match: Checks if the collection name exists exactly + *
  2. Shard Match: Checks if any shards start with "collection{@value + * #SHARD_SUFFIX}" pattern + *
+ * + *

This dual approach ensures compatibility with both standalone Solr (which returns core + * names directly) and SolrCloud (which may return shard names). + * + *

Error Handling: + * + *

Returns {@code false} if validation fails due to communication errors, allowing calling + * methods to handle missing collections appropriately. + * + * @param collection the collection name to validate + * @return true if the collection exists (either exact or shard match), false otherwise + * @see #listCollections() + * @see #extractCollectionName(String) + */ + private boolean validateCollectionExists(String collection) { + try { + List collections = listCollections(); + + // Check for exact match first + if (collections.contains(collection)) { + return true; + } + + // Check if any of the returned collections start with the collection name (for shard + // names) + return collections.stream().anyMatch(c -> c.startsWith(collection + SHARD_SUFFIX)); + } catch (Exception _) { + return false; + } + } + + /** + * Performs a comprehensive health check on a Solr collection. + * + *

Evaluates collection availability and performance by executing a ping operation and basic + * query to gather health indicators. This method provides a quick way to determine if a + * collection is operational and responding to requests. + * + *

Health Check Components: + * + *

    + *
  • Availability: Collection responds to ping requests + *
  • Performance: Response time measurement + *
  • Content: Document count verification using universal query ({@value + * #ALL_DOCUMENTS_QUERY}) + *
  • Timestamp: When the check was performed + *
+ * + *

Success Criteria: + * + *

A collection is considered healthy if both the ping operation and a basic query complete + * successfully without exceptions. Performance metrics are collected during the health check + * process. + * + *

Failure Handling: + * + *

If the health check fails, a status object is returned with {@code isHealthy=false} and + * the error message describing the failure reason. This allows monitoring systems to identify + * specific issues. + * + *

MCP Tool Usage: + * + *

Exposed as an MCP tool for natural language health queries like "check if my_collection is + * healthy" or "is the search index working properly". + * + * @param collection the name of the collection to health check + * @return SolrHealthStatus object containing health assessment results + * @see SolrHealthStatus + * @see SolrPingResponse + */ + @McpTool(description = "Check health of a Solr collection") + public SolrHealthStatus checkHealth( + @McpToolParam(description = "Solr collection") String collection) { + try { + // Ping Solr + SolrPingResponse pingResponse = solrClient.ping(collection); + + // Get basic stats + QueryResponse statsResponse = + solrClient.query(collection, new SolrQuery(ALL_DOCUMENTS_QUERY).setRows(0)); + + return new SolrHealthStatus( + true, + null, + pingResponse.getElapsedTime(), + statsResponse.getResults().getNumFound(), + new Date(), + null, + null, + null); + + } catch (Exception error) { + return new SolrHealthStatus( + false, error.getMessage(), null, null, new Date(), null, null, null); + } + } +} diff --git a/src/main/java/org/apache/solr/mcp/server/metadata/CollectionUtils.java b/src/main/java/org/apache/solr/mcp/server/metadata/CollectionUtils.java new file mode 100644 index 0000000..9c8bfbd --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/metadata/CollectionUtils.java @@ -0,0 +1,205 @@ +package org.apache.solr.mcp.server.metadata; + +import org.apache.solr.common.util.NamedList; + +/** + * Utility class providing type-safe helper methods for extracting values from Apache Solr NamedList + * objects. + * + *

This utility class simplifies the process of working with Solr's {@code NamedList} response + * format by providing robust type conversion methods that handle various data formats and edge + * cases commonly encountered when processing Solr admin and query responses. + * + *

Key Benefits: + * + *

    + *
  • Type Safety: Automatic conversion with proper error handling + *
  • Null Safety: Graceful handling of missing or null values + *
  • Format Flexibility: Support for multiple input data types + *
  • Error Resilience: Defensive programming against malformed data + *
+ * + *

Common Use Cases: + * + *

    + *
  • Extracting metrics from Solr MBeans responses + *
  • Processing Luke handler index statistics + *
  • Converting admin API response values to typed objects + *
  • Handling cache and handler performance metrics + *
+ * + *

Thread Safety: + * + *

All methods in this utility class are stateless and thread-safe, making them suitable for use + * in concurrent environments and Spring service beans. + * + * @author adityamparikh + * @version 0.0.1 + * @see org.apache.solr.common.util.NamedList + * @see CollectionService + * @since 0.0.1 + */ +public class CollectionUtils { + + /** + * Private constructor to prevent instantiation of this utility class. + */ + private CollectionUtils() { + throw new UnsupportedOperationException("Utility class"); + } + + /** + * Extracts a Long value from a NamedList using the specified key with robust type conversion. + * + *

This method provides flexible extraction of Long values from Solr NamedList responses, + * handling various input formats that may be returned by different Solr endpoints. It performs + * safe type conversion with appropriate error handling for malformed data. + * + *

Supported Input Types: + * + *

    + *
  • Number instances: Integer, Long, Double, Float, BigInteger, BigDecimal + *
  • String representations: Numeric strings that can be parsed as Long + *
  • Null values: Returns null without throwing exceptions + *
+ * + *

Error Handling: + * + *

Returns {@code null} for missing keys, null values, or unparseable strings rather than + * throwing exceptions, enabling graceful degradation in metrics collection scenarios. + * + *

Common Use Cases: + * + *

    + *
  • Cache statistics: hits, lookups, evictions, size + *
  • Handler metrics: request counts, error counts, timeouts + *
  • Index statistics: document counts, segment information + *
+ * + * @param response the NamedList containing the data to extract from + * @param key the key to look up in the NamedList + * @return the Long value if found and convertible, null otherwise + * @see Number#longValue() + * @see Long#parseLong(String) + */ + public static Long getLong(NamedList response, String key) { + Object value = response.get(key); + if (value == null) return null; + + if (value instanceof Number number) { + return number.longValue(); + } + + try { + return Long.parseLong(value.toString()); + } catch (NumberFormatException _) { + return null; + } + } + + /** + * Extracts a Float value from a NamedList using the specified key with automatic type + * conversion. + * + *

This method provides convenient extraction of Float values from Solr NamedList responses, + * commonly used for extracting percentage values, ratios, and performance metrics. It assumes + * that missing values should be treated as zero, which is appropriate for most metric + * scenarios. + * + *

Type Conversion: + * + *

Automatically converts any Number instance to Float using the {@link Number#floatValue()} + * method, ensuring compatibility with various numeric types returned by Solr. + * + *

Default Value Behavior: + * + *

Returns {@code 0.0f} for missing or null values, which is typically the desired behavior + * for metrics like hit ratios, performance averages, and statistical calculations where missing + * data should be interpreted as zero. + * + *

Common Use Cases: + * + *

    + *
  • Cache hit ratios and performance percentages + *
  • Average response times and throughput metrics + *
  • Statistical calculations and performance indicators + *
+ * + *

Note: + * + *

This method differs from {@link #getLong(NamedList, String)} by returning a default value + * instead of null, which is more appropriate for Float metrics that represent rates, ratios, or + * averages. + * + * @param stats the NamedList containing the metric data to extract from + * @param key the key to look up in the NamedList + * @return the Float value if found, or 0.0f if the key doesn't exist or value is null + * @see Number#floatValue() + */ + public static Float getFloat(NamedList stats, String key) { + Object value = stats.get(key); + return value != null ? ((Number) value).floatValue() : 0.0f; + } + + /** + * Extracts an Integer value from a NamedList using the specified key with robust type + * conversion. + * + *

This method provides flexible extraction of Integer values from Solr NamedList responses, + * handling various input formats that may be returned by different Solr endpoints. It performs + * safe type conversion with appropriate error handling for malformed data. + * + *

Supported Input Types: + * + *

    + *
  • Number instances: Integer, Long, Double, Float, BigInteger, BigDecimal + *
  • String representations: Numeric strings that can be parsed as Integer + *
  • Null values: Returns null without throwing exceptions + *
+ * + *

Type Conversion Strategy: + * + *

For Number instances, uses {@link Number#intValue()} which truncates decimal values. For + * string values, attempts parsing with {@link Integer#parseInt(String)} and returns null if + * parsing fails rather than throwing an exception. + * + *

Error Handling: + * + *

Returns {@code null} for missing keys, null values, or unparseable strings rather than + * throwing exceptions, enabling graceful degradation in metrics collection scenarios. + * + *

Common Use Cases: + * + *

    + *
  • Index segment counts and document counts (when within Integer range) + *
  • Configuration values and small numeric metrics + *
  • Count-based statistics that don't exceed Integer.MAX_VALUE + *
+ * + *

Range Considerations: + * + *

For large values that may exceed Integer range, consider using {@link #getLong(NamedList, + * String)} instead to avoid truncation or overflow issues. + * + * @param response the NamedList containing the data to extract from + * @param key the key to look up in the NamedList + * @return the Integer value if found and convertible, null otherwise + * @see Number#intValue() + * @see Integer#parseInt(String) + * @see #getLong(NamedList, String) + */ + public static Integer getInteger(NamedList response, String key) { + Object value = response.get(key); + if (value == null) return null; + + if (value instanceof Number number) { + return number.intValue(); + } + + try { + return Integer.parseInt(value.toString()); + } catch (NumberFormatException _) { + return null; + } + } +} diff --git a/src/main/java/org/apache/solr/mcp/server/metadata/Dtos.java b/src/main/java/org/apache/solr/mcp/server/metadata/Dtos.java new file mode 100644 index 0000000..68e0459 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/metadata/Dtos.java @@ -0,0 +1,401 @@ +package org.apache.solr.mcp.server.metadata; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; + +import java.util.Date; + +/** + * Data Transfer Objects (DTOs) for the Apache Solr MCP Server. + * + *

This package contains all the data transfer objects used to serialize and deserialize Solr + * metrics, search results, and health status information for Model Context Protocol (MCP) clients. + * All DTOs use Java records for immutability and Jackson annotations for JSON serialization. + * + *

Key Features: + * + *

    + *
  • Automatic null value exclusion from JSON output using + * {@code @JsonInclude(JsonInclude.Include.NON_NULL)} + *
  • Resilient JSON parsing with {@code @JsonIgnoreProperties(ignoreUnknown = true)} + *
  • Immutable data structures using Java records + *
  • ISO 8601 timestamp formatting for consistent date serialization + *
+ * + * @author adityamparikh + * @version 0.0.1 + * @since 0.0.1 + */ + +/** + * Top-level container for comprehensive Solr collection metrics. + * + *

This class aggregates various types of Solr performance and operational metrics including + * index statistics, query performance, cache utilization, and request handler metrics. It serves as + * the primary response object for collection monitoring and analysis tools. + * + *

The metrics are collected from multiple Solr admin endpoints and MBeans to provide a + * comprehensive view of collection health and performance characteristics. + * + *

Null-Safe Design: + * + *

Individual metric components (cache stats, handler stats) may be null if the corresponding + * data is unavailable or empty. Always check for null values before accessing nested properties. + * + *

Example usage: + * + *

{@code
+ * SolrMetrics metrics = collectionService.getCollectionStats("my_collection");
+ * System.out.println("Documents: " + metrics.getIndexStats().getNumDocs());
+ *
+ * // Safe null checking for optional metrics
+ * if (metrics.getCacheStats() != null && metrics.getCacheStats().getQueryResultCache() != null) {
+ *     System.out.println("Cache hit ratio: " + metrics.getCacheStats().getQueryResultCache().getHitratio());
+ * }
+ * }
+ * + * @see IndexStats + * @see QueryStats + * @see CacheStats + * @see HandlerStats + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +record SolrMetrics( + /** Index-related statistics including document counts and segment information */ + IndexStats indexStats, + + /** Query performance metrics from the most recent search operations */ + QueryStats queryStats, + + /** + * Cache utilization statistics for query result, document, and filter caches (may be null) + */ + CacheStats cacheStats, + + /** Request handler performance metrics for select and update operations (may be null) */ + HandlerStats handlerStats, + + /** Timestamp when these metrics were collected, formatted as ISO 8601 */ + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + Date timestamp) { +} + +/** + * Lucene index statistics for a Solr collection. + * + *

Provides essential information about the underlying Lucene index structure and document + * composition. These metrics are retrieved using Solr's Luke request handler which exposes + * Lucene-level index information. + * + *

Available Metrics: + * + *

    + *
  • numDocs: Total number of documents excluding deleted documents + *
  • segmentCount: Number of Lucene segments (affects search performance) + *
+ * + *

Performance Implications: + * + *

High segment counts may indicate the need for index optimization to improve search + * performance. The optimal segment count depends on index size and update frequency. + * + * @see org.apache.solr.client.solrj.request.LukeRequest + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +record IndexStats( + /** Total number of documents in the index (excluding deleted documents) */ + Integer numDocs, + + /** + * Number of Lucene segments in the index (lower numbers generally indicate better + * performance) + */ + Integer segmentCount) { +} + +/** + * Field-level statistics for individual Solr schema fields. + * + *

Provides detailed information about how individual fields are utilized within the Solr index. + * This information helps with schema optimization and understanding field usage patterns. + * + *

Statistics include: + * + *

    + *
  • type: Solr field type (e.g., "text_general", "int", "date") + *
  • docs: Number of documents containing this field + *
  • distinct: Number of unique values for this field + *
+ * + *

Analysis Insights: + * + *

High cardinality fields (high distinct values) may require special indexing considerations, + * while sparsely populated fields (low docs count) might benefit from different storage strategies. + * + *

Note: This class is currently unused in the collection statistics but is + * available for future field-level analysis features. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +record FieldStats( + /** Solr field type as defined in the schema configuration */ + String type, + + /** Number of documents in the index that contain this field */ + Integer docs, + + /** Number of unique/distinct values for this field across all documents */ + Integer distinct) { +} + +/** + * Query execution performance metrics from Solr search operations. + * + *

Captures performance characteristics and result metadata from the most recent query execution. + * These metrics help identify query performance patterns and potential optimization opportunities. + * + *

Available Metrics: + * + *

    + *
  • queryTime: Time in milliseconds to execute the query + *
  • totalResults: Total number of matching documents found + *
  • start: Starting offset for pagination + *
  • maxScore: Highest relevance score in the result set + *
+ * + *

Performance Analysis: + * + *

Query time metrics help identify slow queries that may need optimization, while result counts + * and scores provide insight into search effectiveness and relevance tuning needs. + * + * @see org.apache.solr.client.solrj.response.QueryResponse + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +record QueryStats( + /** Time in milliseconds required to execute the most recent query */ + Integer queryTime, + + /** Total number of documents matching the query criteria */ + Long totalResults, + + /** Starting position for paginated results (0-based offset) */ + Long start, + + /** Highest relevance score among the returned documents */ + Float maxScore) { +} + +/** + * Solr cache utilization statistics across all cache types. + * + *

Aggregates cache performance metrics for the three primary Solr caches. Cache performance + * directly impacts query response times and system resource utilization, making these metrics + * critical for performance tuning. + * + *

Monitored Cache Types: + * + *

    + *
  • queryResultCache: Caches complete query results + *
  • documentCache: Caches retrieved document data + *
  • filterCache: Caches filter query results + *
+ * + *

Cache Analysis: + * + *

Poor cache hit ratios may indicate undersized caches or query patterns that don't benefit from + * caching. Cache evictions suggest memory pressure or cache size optimization needs. + * + * @see CacheInfo + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +record CacheStats( + /** Performance metrics for the query result cache */ + CacheInfo queryResultCache, + + /** Performance metrics for the document cache */ + CacheInfo documentCache, + + /** Performance metrics for the filter cache */ + CacheInfo filterCache) { +} + +/** + * Detailed performance metrics for individual Solr cache instances. + * + *

Provides comprehensive cache utilization statistics including hit ratios, eviction rates, and + * current size metrics. These metrics are essential for cache tuning and memory management + * optimization. + * + *

Key Performance Indicators: + * + *

    + *
  • hitratio: Cache effectiveness (higher is better) + *
  • evictions: Memory pressure indicator + *
  • size: Current cache utilization + *
  • lookups vs hits: Cache request patterns + *
+ * + *

Performance Targets: + * + *

Optimal cache performance typically shows high hit ratios (>0.80) with minimal evictions. High + * eviction rates suggest cache size increases may improve performance. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +record CacheInfo( + /** Total number of cache lookup requests */ + Long lookups, + + /** Number of successful cache hits */ + Long hits, + + /** Cache hit ratio (hits/lookups) - higher values indicate better cache performance */ + Float hitratio, + + /** Number of new entries added to the cache */ + Long inserts, + + /** Number of entries removed due to cache size limits (indicates memory pressure) */ + Long evictions, + + /** Current number of entries stored in the cache */ + Long size) { +} + +/** + * Request handler performance statistics for core Solr operations. + * + *

Tracks performance metrics for the primary Solr request handlers that process search and + * update operations. Handler performance directly affects user experience and system throughput + * capacity. + * + *

Monitored Handlers: + * + *

    + *
  • selectHandler: Processes search/query requests (/select) + *
  • updateHandler: Processes document indexing requests (/update) + *
+ * + *

Performance Analysis: + * + *

Handler metrics help identify bottlenecks in request processing and guide capacity planning + * decisions. High error rates or response times indicate potential optimization needs. + * + * @see HandlerInfo + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +record HandlerStats( + /** Performance metrics for the search/select request handler */ + HandlerInfo selectHandler, + + /** Performance metrics for the document update request handler */ + HandlerInfo updateHandler) { +} + +/** + * Detailed performance metrics for individual Solr request handlers. + * + *

Provides comprehensive request handler statistics including throughput, error rates, and + * performance characteristics. These metrics are crucial for identifying performance bottlenecks + * and system reliability issues. + * + *

Performance Metrics: + * + *

    + *
  • requests: Total volume processed + *
  • errors: Reliability indicator + *
  • avgTimePerRequest: Response time performance + *
  • avgRequestsPerSecond: Throughput capacity + *
+ * + *

Health Indicators: + * + *

High error rates may indicate system stress or configuration issues. Increasing response times + * suggest capacity limits or optimization needs. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +record HandlerInfo( + /** Total number of requests processed by this handler */ + Long requests, + + /** Number of requests that resulted in errors */ + Long errors, + + /** Number of requests that exceeded timeout limits */ + Long timeouts, + + /** Cumulative time spent processing all requests (milliseconds) */ + Long totalTime, + + /** Average time per request in milliseconds */ + Float avgTimePerRequest, + + /** Average throughput in requests per second */ + Float avgRequestsPerSecond) { +} + +/** + * Comprehensive health status assessment for Solr collections. + * + *

Provides a complete health check result including availability status, performance metrics, + * and diagnostic information. This serves as a primary monitoring endpoint for collection + * operational status. + * + *

Health Assessment Components: + * + *

    + *
  • isHealthy: Overall collection availability + *
  • responseTime: Performance indicator + *
  • totalDocuments: Content availability + *
  • errorMessage: Diagnostic information when unhealthy + *
+ * + *

Monitoring Integration: + * + *

This DTO is typically used by monitoring systems and dashboards to provide real-time + * collection health status and enable automated alerting on failures. + * + *

Example usage: + * + *

{@code
+ * SolrHealthStatus status = collectionService.checkHealth("my_collection");
+ * if (!status.isHealthy()) {
+ *     logger.error("Collection unhealthy: " + status.getErrorMessage());
+ * }
+ * }
+ */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +record SolrHealthStatus( + /** Overall health status - true if collection is operational and responding */ + boolean isHealthy, + + /** Detailed error message when isHealthy is false, null when healthy */ + String errorMessage, + + /** Response time in milliseconds for the health check ping request */ + Long responseTime, + + /** Total number of documents currently indexed in the collection */ + Long totalDocuments, + + /** Timestamp when this health check was performed, formatted as ISO 8601 */ + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + Date lastChecked, + + /** Name of the collection that was checked */ + String collection, + + /** Version of Solr server (when available) */ + String solrVersion, + + /** Additional status information or state description */ + String status) { +} diff --git a/src/main/java/org/apache/solr/mcp/server/metadata/SchemaService.java b/src/main/java/org/apache/solr/mcp/server/metadata/SchemaService.java new file mode 100644 index 0000000..3c7bb6d --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/metadata/SchemaService.java @@ -0,0 +1,175 @@ +package org.apache.solr.mcp.server.metadata; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.request.schema.SchemaRequest; +import org.apache.solr.client.solrj.response.schema.SchemaRepresentation; +import org.springaicommunity.mcp.annotation.McpTool; +import org.springframework.stereotype.Service; + +import java.io.IOException; + +/** + * Spring Service providing schema introspection and management capabilities for Apache Solr + * collections. + * + *

This service enables exploration and analysis of Solr collection schemas through the Model + * Context Protocol (MCP), allowing AI clients to understand field definitions, data types, and + * schema configuration for intelligent query construction and data analysis workflows. + * + *

Core Capabilities: + * + *

    + *
  • Schema Retrieval: Complete schema information for any collection + *
  • Field Introspection: Detailed field type and configuration analysis + *
  • Dynamic Field Support: Discovery of dynamic field patterns and rules + *
  • Copy Field Analysis: Understanding of field copying and aggregation rules + *
+ * + *

Schema Information Provided: + * + *

    + *
  • Field Definitions: Names, types, indexing, and storage configurations + *
  • Field Types: Analyzer configurations, tokenization, and filtering rules + *
  • Dynamic Fields: Pattern-based field matching and type assignment + *
  • Copy Fields: Source-to-destination field copying configurations + *
  • Unique Key: Primary key field identification and configuration + *
+ * + *

MCP Tool Integration: + * + *

Schema operations are exposed as MCP tools that AI clients can invoke through natural language + * requests such as "show me the schema for my_collection" or "what fields are available for + * searching in the products index". + * + *

Use Cases: + * + *

    + *
  • Query Planning: Understanding available fields for search construction + *
  • Data Analysis: Identifying field types and capabilities for analytics + *
  • Index Optimization: Analyzing field configurations for performance tuning + *
  • Schema Documentation: Generating documentation from live schema + * definitions + *
+ * + *

Integration with Other Services: + * + *

Schema information complements other MCP services by providing the metadata necessary for + * intelligent search query construction, field validation, and result interpretation. + * + *

Example Usage: + * + *

{@code
+ * // Get complete schema information
+ * SchemaRepresentation schema = schemaService.getSchema("products");
+ *
+ * // Analyze field configurations
+ * schema.getFields().forEach(field -> {
+ *     System.out.println("Field: " + field.getName() + " Type: " + field.getType());
+ * });
+ *
+ * // Examine dynamic field patterns
+ * schema.getDynamicFields().forEach(dynField -> {
+ *     System.out.println("Pattern: " + dynField.getName() + " Type: " + dynField.getType());
+ * });
+ * }
+ * + * @author adityamparikh + * @version 0.0.1 + * @see SchemaRepresentation + * @see org.apache.solr.client.solrj.request.schema.SchemaRequest + * @see org.springframework.ai.tool.annotation.Tool + * @since 0.0.1 + */ +@Service +public class SchemaService { + + /** + * SolrJ client for communicating with Solr server + */ + private final SolrClient solrClient; + + /** + * Constructs a new SchemaService with the required SolrClient dependency. + * + *

This constructor is automatically called by Spring's dependency injection framework during + * application startup, providing the service with the necessary Solr client for schema + * operations. + * + * @param solrClient the SolrJ client instance for communicating with Solr + * @see SolrClient + */ + public SchemaService(SolrClient solrClient) { + this.solrClient = solrClient; + } + + /** + * Retrieves the complete schema definition for a specified Solr collection. + * + *

This method provides comprehensive access to all schema components including field + * definitions, field types, dynamic fields, copy fields, and schema-level configuration. The + * returned schema representation contains all information necessary for understanding the + * collection's data structure and capabilities. + * + *

Schema Components Included: + * + *

    + *
  • Fields: Static field definitions with types and properties + *
  • Field Types: Analyzer configurations and processing rules + *
  • Dynamic Fields: Pattern-based field matching rules + *
  • Copy Fields: Field copying and aggregation configurations + *
  • Unique Key: Primary key field specification + *
  • Schema Attributes: Version, name, and global settings + *
+ * + *

Field Information Details: + * + *

Each field definition includes comprehensive metadata: + * + *

    + *
  • Name: Field identifier for queries and indexing + *
  • Type: Reference to field type configuration + *
  • Indexed: Whether the field is searchable + *
  • Stored: Whether field values are retrievable + *
  • Multi-valued: Whether multiple values are allowed + *
  • Required: Whether the field must have a value + *
+ * + *

MCP Tool Usage: + * + *

AI clients can invoke this method with natural language requests such as: + * + *

    + *
  • "Show me the schema for the products collection" + *
  • "What fields are available in my_index?" + *
  • "Get the field definitions for the search index" + *
+ * + *

Error Handling: + * + *

If the collection does not exist or schema retrieval fails, the method will throw an + * exception with details about the failure reason. Common issues include collection name typos, + * permission problems, or Solr connectivity issues. + * + *

Performance Considerations: + * + *

Schema information is typically cached by Solr and retrieval is generally fast. However, + * for applications that frequently access schema information, consider implementing client-side + * caching to reduce network overhead. + * + * @param collection the name of the Solr collection to retrieve schema information for + * @return complete schema representation containing all field and type definitions + * @throws SolrServerException if collection does not exist, access is denied, or Solr server + * error occurs + * @throws IOException if communication with Solr server fails + * @see SchemaRepresentation + * @see SchemaRequest + * @see org.apache.solr.client.solrj.response.schema.SchemaResponse + */ + @McpTool(description = "Get schema for a Solr collection") + public SchemaRepresentation getSchema(String collection) + throws SolrServerException, IOException { + SchemaRequest schemaRequest = new SchemaRequest(); + return schemaRequest.process(solrClient, collection).getSchemaRepresentation(); + } +} diff --git a/src/main/java/org/apache/solr/mcp/server/package-info.java b/src/main/java/org/apache/solr/mcp/server/package-info.java new file mode 100644 index 0000000..37873ec --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.apache.solr.mcp.server; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/apache/solr/mcp/server/search/SearchResponse.java b/src/main/java/org/apache/solr/mcp/server/search/SearchResponse.java new file mode 100644 index 0000000..b061d06 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/search/SearchResponse.java @@ -0,0 +1,103 @@ +package org.apache.solr.mcp.server.search; + +import java.util.List; +import java.util.Map; + +/** + * Immutable record representing a structured search response from Apache Solr operations. + * + *

This record encapsulates all essential components of a Solr search result in a type-safe, + * immutable structure that can be easily serialized to JSON for MCP client consumption. It provides + * a clean abstraction over Solr's native response format while preserving all critical search + * metadata and result data. + * + *

Record Benefits: + * + *

    + *
  • Immutability: Response data cannot be modified after creation + *
  • Type Safety: Compile-time validation of response structure + *
  • JSON Serialization: Automatic conversion to JSON for MCP clients + *
  • Memory Efficiency: Compact representation with minimal overhead + *
+ * + *

Search Metadata: + * + *

The response includes comprehensive search metadata that helps clients understand the query + * results and implement pagination, relevance analysis, and user interfaces: + * + *

    + *
  • Total Results: Complete count of matching documents + *
  • Pagination Info: Current offset for result windowing + *
  • Relevance Scoring: Maximum relevance score in the result set + *
+ * + *

Document Structure: + * + *

Documents are represented as flexible key-value maps to accommodate Solr's dynamic field + * capabilities and schema-less operation. Each document map contains field names as keys and field + * values as objects, preserving the original data types from Solr (strings, numbers, dates, arrays, + * etc.). + * + *

Faceting Support: + * + *

Facet information is structured as a nested map hierarchy where the outer map represents facet + * field names and inner maps contain facet values with their corresponding document counts. This + * structure efficiently supports multiple faceting strategies including field faceting and range + * faceting. + * + *

Usage Examples: + * + *

{@code
+ * // Access search results
+ * SearchResponse response = searchService.search("products", "laptop", null, null, null, 0, 10);
+ * System.out.println("Found " + response.numFound() + " products");
+ *
+ * // Iterate through documents
+ * for (Map doc : response.documents()) {
+ *     System.out.println("Title: " + doc.get("title"));
+ *     System.out.println("Price: " + doc.get("price"));
+ * }
+ *
+ * // Access facet data
+ * Map categoryFacets = response.facets().get("category");
+ * categoryFacets.forEach((category, count) ->
+ *     System.out.println(category + ": " + count + " items"));
+ * }
+ * + *

JSON Serialization Example: + * + *

{@code
+ * {
+ *   "numFound": 150,
+ *   "start": 0,
+ *   "maxScore": 2.34,
+ *   "documents": [
+ *     {"id": "1", "title": "Product 1", "price": 29.99},
+ *     {"id": "2", "title": "Product 2", "price": 19.99}
+ *   ],
+ *   "facets": {
+ *     "category": {"electronics": 45, "books": 30},
+ *     "brand": {"apple": 12, "samsung": 8}
+ *   }
+ * }
+ * }
+ * + * @param numFound total number of documents matching the search query across all pages + * @param start zero-based offset indicating the starting position of returned results + * @param maxScore highest relevance score among the returned documents (null if scoring disabled) + * @param documents list of document maps containing field names and values for each result + * @param facets nested map structure containing facet field names, values, and document counts + * @author adityamparikh + * @version 0.0.1 + * @see SearchService#search(String, String, List, List, List, Integer, Integer) + * @see org.apache.solr.client.solrj.response.QueryResponse + * @see org.apache.solr.common.SolrDocumentList + * @since 0.0.1 + */ +public record SearchResponse( + long numFound, + long start, + Float maxScore, + List> documents, + Map> facets) { +} diff --git a/src/main/java/org/apache/solr/mcp/server/search/SearchService.java b/src/main/java/org/apache/solr/mcp/server/search/SearchService.java new file mode 100644 index 0000000..c98cf12 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/search/SearchService.java @@ -0,0 +1,273 @@ +package org.apache.solr.mcp.server.search; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.response.FacetField; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocumentList; +import org.apache.solr.common.params.FacetParams; +import org.springaicommunity.mcp.annotation.McpTool; +import org.springaicommunity.mcp.annotation.McpToolParam; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Spring Service providing comprehensive search capabilities for Apache Solr collections through + * Model Context Protocol (MCP) integration. + * + *

This service serves as the primary interface for executing search operations against Solr + * collections, offering a rich set of features including text search, filtering, faceting, sorting, + * and pagination. It transforms complex Solr query syntax into accessible MCP tools that AI clients + * can invoke through natural language requests. + * + *

Core Features: + * + *

    + *
  • Full-Text Search: Advanced text search with relevance scoring + *
  • Filtering: Multi-criteria filtering using Solr filter queries + *
  • Faceting: Dynamic facet generation for result categorization + *
  • Sorting: Flexible result ordering by multiple fields + *
  • Pagination: Efficient handling of large result sets + *
+ * + *

Dynamic Field Support: + * + *

The service handles Solr's dynamic field naming conventions where field names include type + * suffixes that indicate data types and indexing behavior: + * + *

    + *
  • _s: String fields for exact matching + *
  • _t: Text fields with tokenization and analysis + *
  • _i, _l, _f, _d: Numeric fields (int, long, float, double) + *
  • _dt: Date/time fields + *
  • _b: Boolean fields + *
+ * + *

MCP Tool Integration: + * + *

Search operations are exposed as MCP tools that AI clients can invoke through natural language + * requests such as "search for books by George R.R. Martin" or "find products under $50 in the + * electronics category". + * + *

Response Format: + * + *

Returns structured {@link SearchResponse} objects that encapsulate search results, metadata, + * and facet information in a format optimized for JSON serialization and consumption by AI clients. + * + * @author adityamparikh + * @version 0.0.1 + * @see SearchResponse + * @see SolrClient + * @see org.springframework.ai.tool.annotation.Tool + * @since 0.0.1 + */ +@Service +public class SearchService { + + public static final String SORT_ITEM = "item"; + public static final String SORT_ORDER = "order"; + private final SolrClient solrClient; + + /** + * Constructs a new SearchService with the required SolrClient dependency. + * + *

This constructor is automatically called by Spring's dependency injection framework during + * application startup, providing the service with the necessary Solr client for executing + * search operations. + * + * @param solrClient the SolrJ client instance for communicating with Solr + * @see SolrClient + */ + public SearchService(SolrClient solrClient) { + this.solrClient = solrClient; + } + + /** + * Converts a SolrDocumentList to a List of Maps for optimized JSON serialization. + * + *

This method transforms Solr's native document format into a structure that can be easily + * serialized to JSON and consumed by MCP clients. Each document becomes a flat map of field + * names to field values, preserving all data types. + * + *

Conversion Process: + * + *

    + *
  • Iterates through each SolrDocument in the list + *
  • Extracts all field names and their corresponding values + *
  • Creates a HashMap for each document with field-value pairs + *
  • Preserves original data types (strings, numbers, dates, arrays) + *
+ * + *

Performance Optimization: + * + *

Pre-allocates the ArrayList with the known document count to minimize memory allocations + * and improve conversion performance for large result sets. + * + * @param documents the SolrDocumentList to convert from Solr's native format + * @return a List of Maps where each Map represents a document with field names as keys + * @see org.apache.solr.common.SolrDocument + * @see org.apache.solr.common.SolrDocumentList + */ + private static List> getDocs(SolrDocumentList documents) { + List> docs = new java.util.ArrayList<>(documents.size()); + documents.forEach( + doc -> { + Map docMap = new HashMap<>(); + for (String fieldName : doc.getFieldNames()) { + docMap.put(fieldName, doc.getFieldValue(fieldName)); + } + docs.add(docMap); + }); + return docs; + } + + /** + * Extracts facet information from a QueryResponse. + * + * @param queryResponse The QueryResponse containing facet results + * @return A Map where keys are facet field names and values are Maps of facet values to counts + */ + private static Map> getFacets(QueryResponse queryResponse) { + Map> facets = new HashMap<>(); + if (queryResponse.getFacetFields() != null && !queryResponse.getFacetFields().isEmpty()) { + queryResponse + .getFacetFields() + .forEach( + facetField -> { + Map facetValues = new HashMap<>(); + for (FacetField.Count count : facetField.getValues()) { + facetValues.put(count.getName(), count.getCount()); + } + facets.put(facetField.getName(), facetValues); + }); + } + return facets; + } + + /** + * Searches a Solr collection with the specified parameters. This method is exposed as a tool + * for MCP clients to use. + * + * @param collection The Solr collection to query + * @param query The Solr query string (q parameter). Defaults to "*:*" if not specified + * @param filterQueries List of filter queries (fq parameter) + * @param facetFields List of fields to facet on + * @param sortClauses List of sort clauses for ordering results + * @param start Starting offset for pagination + * @param rows Number of rows to return + * @return A SearchResponse containing the search results and facets + * @throws SolrServerException If there's an error communicating with Solr + * @throws IOException If there's an I/O error + */ + @McpTool( + name = "Search", + description = + """ + Search specified Solr collection with query, optional filters, facets, sorting, and pagination. + Note that solr has dynamic fields where name of field in schema may end with suffixes + _s: Represents a string field, used for exact string matching. + _i: Represents an integer field. + _l: Represents a long field. + _f: Represents a float field. + _d: Represents a double field. + _dt: Represents a date field. + _b: Represents a boolean field. + _t: Often used for text fields that undergo tokenization and analysis. + One example from the books collection: + { + "id":"0553579908", + "cat":["book"], + "name":["A Clash of Kings"], + "price":[7.99], + "inStock":[true], + "author":["George R.R. Martin"], + "series_t":"A Song of Ice and Fire", + "sequence_i":2, + "genre_s":"fantasy", + "_version_":1836275819373133824, + "_root_":"0553579908" + } + """) + public SearchResponse search( + @McpToolParam(description = "Solr collection to query") String collection, + @McpToolParam( + description = "Solr q parameter. If none specified defaults to \"*:*\"", + required = false) + String query, + @McpToolParam(description = "Solr fq parameter", required = false) + List filterQueries, + @McpToolParam(description = "Solr facet fields", required = false) + List facetFields, + @McpToolParam(description = "Solr sort parameter", required = false) + List> sortClauses, + @McpToolParam(description = "Starting offset for pagination", required = false) + Integer start, + @McpToolParam(description = "Number of rows to return", required = false) Integer rows) + throws SolrServerException, IOException { + + // query + final SolrQuery solrQuery = new SolrQuery("*:*"); + if (StringUtils.hasText(query)) { + solrQuery.setQuery(query); + } + + // filter queries + if (!CollectionUtils.isEmpty(filterQueries)) { + solrQuery.setFilterQueries(filterQueries.toArray(new String[0])); + } + + // facets + if (!CollectionUtils.isEmpty(facetFields)) { + solrQuery.setFacet(true); + solrQuery.addFacetField(facetFields.toArray(new String[0])); + solrQuery.setFacetMinCount(1); + solrQuery.setFacetSort(FacetParams.FACET_SORT_COUNT); + } + + // sorting + if (!CollectionUtils.isEmpty(sortClauses)) { + solrQuery.setSorts( + sortClauses.stream() + .map( + sortClause -> + new SolrQuery.SortClause( + sortClause.get(SORT_ITEM), + sortClause.get(SORT_ORDER))) + .toList()); + } + + // pagination + if (start != null) { + solrQuery.setStart(start); + } + + if (rows != null) { + solrQuery.setRows(rows); + } + + final QueryResponse queryResponse = solrClient.query(collection, solrQuery); + + // Add documents + final SolrDocumentList documents = queryResponse.getResults(); + + // Convert SolrDocuments to Maps + final var docs = getDocs(documents); + + // Add facets if present + final var facets = getFacets(queryResponse); + + return new SearchResponse( + documents.getNumFound(), + documents.getStart(), + documents.getMaxScore(), + docs, + facets); + } +} diff --git a/src/main/resources/application-http.properties b/src/main/resources/application-http.properties new file mode 100644 index 0000000..601b04e --- /dev/null +++ b/src/main/resources/application-http.properties @@ -0,0 +1,5 @@ +spring.main.web-application-type=servlet +sever.port=8080 +spring.ai.mcp.server.type=sync +spring.ai.mcp.server.protocol=stateless +spring.ai.mcp.server.stdio=false \ No newline at end of file diff --git a/src/main/resources/application-stdio.properties b/src/main/resources/application-stdio.properties new file mode 100644 index 0000000..6ddb125 --- /dev/null +++ b/src/main/resources/application-stdio.properties @@ -0,0 +1,7 @@ +spring.main.web-application-type=none +# NOTE: You must disable the banner and the console logging +# to allow the STDIO transport to work !!! +spring.main.banner-mode=off +logging.pattern.console= +spring.ai.mcp.server.stdio=true + diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..4be311c --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,7 @@ +spring.application.name=solr-mcp-server +spring.profiles.active=${PROFILES:stdio} +spring.ai.mcp.server.instructions=This server provides tools to interact with Apache Solr using Model Context Protocol (MCP) over STDIO and/or HTTP. +spring.ai.mcp.server.name=${spring.application.name} +spring.ai.mcp.server.version=0.0.1 +# Solr configuration +solr.url=${SOLR_URL:http://localhost:8983/solr/} diff --git a/src/test/java/org/apache/solr/mcp/server/ClientHttp.java b/src/test/java/org/apache/solr/mcp/server/ClientHttp.java new file mode 100644 index 0000000..427b0a0 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/ClientHttp.java @@ -0,0 +1,13 @@ +package org.apache.solr.mcp.server; + +import io.modelcontextprotocol.client.transport.HttpClientStreamableHttpTransport; +import org.junit.jupiter.api.Disabled; + +@Disabled("Enable only when MCP server is running in http mode") +public class ClientHttp { + + public static void main(String[] args) { + var transport = HttpClientStreamableHttpTransport.builder("http://localhost:8080").build(); + new SampleClient(transport).run(); + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/ClientStdio.java b/src/test/java/org/apache/solr/mcp/server/ClientStdio.java new file mode 100644 index 0000000..6faa211 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/ClientStdio.java @@ -0,0 +1,28 @@ +package org.apache.solr.mcp.server; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.modelcontextprotocol.client.transport.ServerParameters; +import io.modelcontextprotocol.client.transport.StdioClientTransport; +import io.modelcontextprotocol.json.jackson.JacksonMcpJsonMapper; + +import java.io.File; + +// run after project has been built with "./gradlew build -x test and the mcp server jar is +// connected to a running solr" +public class ClientStdio { + + public static void main(String[] args) { + + System.out.println(new File(".").getAbsolutePath()); + + var stdioParams = + ServerParameters.builder("java") + .args("-jar", "build/libs/solr-mcp-server-0.0.1-SNAPSHOT.jar") + .build(); + + var transport = + new StdioClientTransport(stdioParams, new JacksonMcpJsonMapper(new ObjectMapper())); + + new SampleClient(transport).run(); + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/MainTest.java b/src/test/java/org/apache/solr/mcp/server/MainTest.java new file mode 100644 index 0000000..6bc88c2 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/MainTest.java @@ -0,0 +1,37 @@ +package org.apache.solr.mcp.server; + +import org.apache.solr.mcp.server.indexing.IndexingService; +import org.apache.solr.mcp.server.metadata.CollectionService; +import org.apache.solr.mcp.server.metadata.SchemaService; +import org.apache.solr.mcp.server.search.SearchService; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.bean.override.mockito.MockitoBean; + +/** + * Application context loading test with mocked services. This test verifies that the Spring + * application context can be loaded successfully without requiring actual Solr connections, using + * mocked beans to prevent external dependencies. + */ +@SpringBootTest +@ActiveProfiles("test") +class MainTest { + + @MockitoBean + private SearchService searchService; + + @MockitoBean + private IndexingService indexingService; + + @MockitoBean + private CollectionService collectionService; + + @MockitoBean + private SchemaService schemaService; + + @Test + void contextLoads() { + // Context loading test - all services are mocked to prevent Solr API calls + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/McpToolRegistrationTest.java b/src/test/java/org/apache/solr/mcp/server/McpToolRegistrationTest.java new file mode 100644 index 0000000..9ddaa2e --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/McpToolRegistrationTest.java @@ -0,0 +1,227 @@ +package org.apache.solr.mcp.server; + +import org.apache.solr.mcp.server.indexing.IndexingService; +import org.apache.solr.mcp.server.metadata.CollectionService; +import org.apache.solr.mcp.server.metadata.SchemaService; +import org.apache.solr.mcp.server.search.SearchService; +import org.junit.jupiter.api.Test; +import org.springaicommunity.mcp.annotation.McpTool; +import org.springaicommunity.mcp.annotation.McpToolParam; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Tests for MCP tool registration and annotation validation. Ensures all services expose their + * methods correctly as MCP tools with proper annotations and descriptions. + */ +class McpToolRegistrationTest { + + @Test + void testSearchServiceHasToolAnnotation() throws NoSuchMethodException { + // Get the search method from SearchService + Method searchMethod = + SearchService.class.getMethod( + "search", + String.class, + String.class, + List.class, + List.class, + List.class, + Integer.class, + Integer.class); + + // Verify it has the @McpTool annotation + assertTrue( + searchMethod.isAnnotationPresent(McpTool.class), + "SearchService.search method should have @McpTool annotation"); + + // Verify the annotation properties + McpTool toolAnnotation = searchMethod.getAnnotation(McpTool.class); + assertEquals("Search", toolAnnotation.name(), "McpTool name should be 'Search'"); + assertNotNull(toolAnnotation.description(), "McpTool description should not be null"); + assertFalse( + toolAnnotation.description().isBlank(), "McpTool description should not be blank"); + } + + @Test + void testSearchServiceToolParametersHaveAnnotations() throws NoSuchMethodException { + // Get the search method + Method searchMethod = + SearchService.class.getMethod( + "search", + String.class, + String.class, + List.class, + List.class, + List.class, + Integer.class, + Integer.class); + + // Verify all parameters have @McpToolParam annotations + Parameter[] parameters = searchMethod.getParameters(); + assertTrue(parameters.length > 0, "Search method should have parameters"); + + for (Parameter param : parameters) { + assertTrue( + param.isAnnotationPresent(McpToolParam.class), + "Parameter " + param.getName() + " should have @McpToolParam annotation"); + + McpToolParam paramAnnotation = param.getAnnotation(McpToolParam.class); + assertNotNull( + paramAnnotation.description(), + "Parameter " + param.getName() + " should have description"); + assertFalse( + paramAnnotation.description().isBlank(), + "Parameter " + param.getName() + " description should not be blank"); + } + } + + @Test + void testIndexingServiceHasToolAnnotations() { + // Get all methods from IndexingService + Method[] methods = IndexingService.class.getDeclaredMethods(); + + // Find methods with @McpTool annotation + List mcpToolMethods = + Arrays.stream(methods).filter(m -> m.isAnnotationPresent(McpTool.class)).toList(); + + // Verify at least one method has the annotation + assertFalse( + mcpToolMethods.isEmpty(), + "IndexingService should have at least one method with @McpTool annotation"); + + // Verify each tool has proper annotations + for (Method method : mcpToolMethods) { + McpTool toolAnnotation = method.getAnnotation(McpTool.class); + assertNotNull(toolAnnotation.name(), "Tool name should not be null"); + assertFalse(toolAnnotation.name().isBlank(), "Tool name should not be blank"); + assertNotNull(toolAnnotation.description(), "Tool description should not be null"); + assertFalse( + toolAnnotation.description().isBlank(), "Tool description should not be blank"); + } + } + + @Test + void testCollectionServiceHasToolAnnotations() { + // Get all methods from CollectionService + Method[] methods = CollectionService.class.getDeclaredMethods(); + + // Find methods with @McpTool annotation + List mcpToolMethods = + Arrays.stream(methods).filter(m -> m.isAnnotationPresent(McpTool.class)).toList(); + + // Verify at least one method has the annotation + assertFalse( + mcpToolMethods.isEmpty(), + "CollectionService should have at least one method with @McpTool annotation"); + + // Verify each tool has proper annotations + for (Method method : mcpToolMethods) { + McpTool toolAnnotation = method.getAnnotation(McpTool.class); + assertNotNull(toolAnnotation.description(), "Tool description should not be null"); + assertFalse( + toolAnnotation.description().isBlank(), "Tool description should not be blank"); + } + } + + @Test + void testSchemaServiceHasToolAnnotations() { + // Get all methods from SchemaService + Method[] methods = SchemaService.class.getDeclaredMethods(); + + // Find methods with @McpTool annotation + List mcpToolMethods = + Arrays.stream(methods).filter(m -> m.isAnnotationPresent(McpTool.class)).toList(); + + // Verify at least one method has the annotation + assertFalse( + mcpToolMethods.isEmpty(), + "SchemaService should have at least one method with @McpTool annotation"); + + // Verify each tool has proper annotations + for (Method method : mcpToolMethods) { + McpTool toolAnnotation = method.getAnnotation(McpTool.class); + assertNotNull(toolAnnotation.description(), "Tool description should not be null"); + assertFalse( + toolAnnotation.description().isBlank(), "Tool description should not be blank"); + } + } + + @Test + void testAllMcpToolsHaveUniqueNames() { + // Collect all MCP tool names from all services + List toolNames = new java.util.ArrayList<>(); + + // SearchService + addToolNames(SearchService.class, toolNames); + + // IndexingService + addToolNames(IndexingService.class, toolNames); + + // CollectionService + addToolNames(CollectionService.class, toolNames); + + // SchemaService + addToolNames(SchemaService.class, toolNames); + + // Verify all tool names are unique + long uniqueCount = toolNames.stream().distinct().count(); + assertEquals( + toolNames.size(), + uniqueCount, + "All MCP tool names should be unique across all services. Found tools: " + + toolNames); + } + + @Test + void testMcpToolParametersFollowConventions() throws NoSuchMethodException { + // Get the search method + Method searchMethod = + SearchService.class.getMethod( + "search", + String.class, + String.class, + List.class, + List.class, + List.class, + Integer.class, + Integer.class); + + Parameter[] parameters = searchMethod.getParameters(); + + // Verify first parameter (collection) is required + McpToolParam firstParam = parameters[0].getAnnotation(McpToolParam.class); + assertTrue( + firstParam.required() || !firstParam.required(), + "First parameter annotation should specify required status"); + + // Verify optional parameters have required=false + for (int i = 1; i < parameters.length; i++) { + McpToolParam param = parameters[i].getAnnotation(McpToolParam.class); + // Optional parameters should be marked as such in description or required flag + assertNotNull( + param.description(), + "Parameter should have description indicating if it's optional"); + } + } + + // Helper method to extract tool names from a service class + private void addToolNames(Class serviceClass, List toolNames) { + Method[] methods = serviceClass.getDeclaredMethods(); + Arrays.stream(methods) + .filter(m -> m.isAnnotationPresent(McpTool.class)) + .forEach( + m -> { + McpTool annotation = m.getAnnotation(McpTool.class); + // Use name if provided, otherwise use method name + String toolName = + annotation.name().isBlank() ? m.getName() : annotation.name(); + toolNames.add(toolName); + }); + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/SampleClient.java b/src/test/java/org/apache/solr/mcp/server/SampleClient.java new file mode 100644 index 0000000..d984382 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/SampleClient.java @@ -0,0 +1,217 @@ +package org.apache.solr.mcp.server; + +import io.modelcontextprotocol.client.McpClient; +import io.modelcontextprotocol.spec.McpClientTransport; +import io.modelcontextprotocol.spec.McpSchema.ListToolsResult; +import io.modelcontextprotocol.spec.McpSchema.Tool; + +import java.util.List; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Sample MCP client for testing and demonstrating Solr MCP Server functionality. + * + *

This test client provides a comprehensive validation suite for the Solr MCP Server, verifying + * that all expected MCP tools are properly registered and functioning as expected. It serves as + * both a testing framework and a reference implementation for MCP client integration. + * + *

Test Coverage: + * + *

    + *
  • Client Initialization: Verifies MCP client can connect and initialize + *
  • Connection Health: Tests ping functionality and connection stability + *
  • Tool Discovery: Validates all expected MCP tools are registered + *
  • Tool Validation: Checks tool metadata, descriptions, and schemas + *
  • Expected Tools: Verifies presence of search, indexing, and metadata tools + *
+ * + *

Expected MCP Tools: + * + *

    + *
  • index_json_documents: JSON document indexing capability + *
  • index_csv_documents: CSV document indexing capability + *
  • index_xml_documents: XML document indexing capability + *
  • Search: Full-text search functionality with filtering and faceting + *
  • listCollections: Collection discovery and listing + *
  • getCollectionStats: Collection metrics and performance data + *
  • checkHealth: Health monitoring and status reporting + *
  • getSchema: Schema introspection and field analysis + *
+ * + *

Usage Example: + * + *

{@code
+ * McpClientTransport transport = // ... initialize transport
+ * SampleClient client = new SampleClient(transport);
+ * client.run(); // Executes full test suite
+ * }
+ * + *

Assertion Strategy: + * + *

Uses JUnit assertions to validate expected behavior and fail fast on any inconsistencies. Each + * tool is validated for proper name, description, and schema configuration to ensure MCP protocol + * compliance. + * + * @author adityamparikh + * @version 0.0.1 + * @see McpClient + * @see McpClientTransport + * @see io.modelcontextprotocol.spec.McpSchema.Tool + * @since 0.0.1 + */ +public class SampleClient { + + private final McpClientTransport transport; + + /** + * Constructs a new SampleClient with the specified MCP transport. + * + * @param transport the MCP client transport for communication with the Solr MCP Server + * @throws IllegalArgumentException if transport is null + */ + public SampleClient(McpClientTransport transport) { + this.transport = transport; + } + + /** + * Executes the comprehensive test suite for Solr MCP Server functionality. + * + *

This method performs a complete validation of the MCP server including: + * + *

    + *
  • Client initialization and connection establishment + *
  • Health check via ping operation + *
  • Tool discovery and count validation + *
  • Individual tool metadata validation + *
  • Tool-specific description and schema verification + *
+ * + *

Test Sequence: + * + *

    + *
  1. Initialize MCP client with provided transport + *
  2. Perform ping test to verify connectivity + *
  3. List all available tools and validate expected count (8 tools) + *
  4. Verify each expected tool is present in the tools list + *
  5. Validate tool metadata (name, description, schema) for each tool + *
  6. Perform tool-specific validation based on tool type + *
+ * + * @throws RuntimeException if any test assertion fails or MCP operations encounter errors + * @throws AssertionError if expected tools are missing or tool validation fails + */ + public void run() { + + try (var client = + McpClient.sync(this.transport) + .loggingConsumer( + message -> System.out.println(">> Client Logging: " + message)) + .build()) { + + // Assert client initialization succeeds + assertDoesNotThrow( + client::initialize, "Client initialization should not throw an exception"); + + // Assert ping succeeds + assertDoesNotThrow(client::ping, "Client ping should not throw an exception"); + + // List and validate tools + ListToolsResult toolsList = client.listTools(); + assertNotNull(toolsList, "Tools list should not be null"); + assertNotNull(toolsList.tools(), "Tools collection should not be null"); + + // Validate expected tool count based on MCP server implementation + assertEquals(8, toolsList.tools().size(), "Expected 8 tools to be available"); + + // Define expected tools based on the log output + Set expectedToolNames = + Set.of( + "index_json_documents", + "index_csv_documents", + "getCollectionStats", + "Search", + "listCollections", + "checkHealth", + "index_xml_documents", + "getSchema"); + + // Validate each expected tool is present + List actualToolNames = toolsList.tools().stream().map(Tool::name).toList(); + + for (String expectedTool : expectedToolNames) { + assertTrue( + actualToolNames.contains(expectedTool), + "Expected tool '" + expectedTool + "' should be available"); + } + + // Validate tool details for key tools + toolsList + .tools() + .forEach( + tool -> { + assertNotNull(tool.name(), "Tool name should not be null"); + assertNotNull( + tool.description(), "Tool description should not be null"); + assertNotNull( + tool.inputSchema(), "Tool input schema should not be null"); + assertFalse( + tool.name().trim().isEmpty(), + "Tool name should not be empty"); + assertFalse( + tool.description().trim().isEmpty(), + "Tool description should not be empty"); + + // Validate specific tools based on expected behavior + switch (tool.name()) { + case "index_json_documents": + assertTrue( + tool.description().toLowerCase().contains("json"), + "JSON indexing tool should mention JSON in" + + " description"); + break; + case "index_csv_documents": + assertTrue( + tool.description().toLowerCase().contains("csv"), + "CSV indexing tool should mention CSV in" + + " description"); + break; + case "Search": + assertTrue( + tool.description().toLowerCase().contains("search"), + "Search tool should mention search in description"); + break; + case "listCollections": + assertTrue( + tool.description() + .toLowerCase() + .contains("collection"), + "List collections tool should mention collections" + + " in description"); + break; + case "checkHealth": + assertTrue( + tool.description().toLowerCase().contains("health"), + "Health check tool should mention health in" + + " description"); + break; + default: + // Additional tools are acceptable + break; + } + + System.out.println( + "Tool: " + + tool.name() + + ", description: " + + tool.description() + + ", schema: " + + tool.inputSchema()); + }); + + } catch (Exception e) { + throw new RuntimeException("MCP client operation failed", e); + } + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/TestcontainersConfiguration.java b/src/test/java/org/apache/solr/mcp/server/TestcontainersConfiguration.java new file mode 100644 index 0000000..23cd4d6 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/TestcontainersConfiguration.java @@ -0,0 +1,31 @@ +package org.apache.solr.mcp.server; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.test.context.DynamicPropertyRegistrar; +import org.testcontainers.containers.SolrContainer; +import org.testcontainers.utility.DockerImageName; + +@TestConfiguration(proxyBeanMethods = false) +public class TestcontainersConfiguration { + + private static final int SOLR_PORT = 8983; + + @Bean + SolrContainer solr() { + return new SolrContainer(DockerImageName.parse("solr:9.9-slim")); + } + + @Bean + DynamicPropertyRegistrar propertiesRegistrar(SolrContainer solr) { + return registry -> + registry.add( + "solr.url", + () -> + "http://" + + solr.getHost() + + ":" + + solr.getMappedPort(SOLR_PORT) + + "/solr/"); + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/config/SolrConfigTest.java b/src/test/java/org/apache/solr/mcp/server/config/SolrConfigTest.java new file mode 100644 index 0000000..1d6bc6b --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/config/SolrConfigTest.java @@ -0,0 +1,168 @@ +package org.apache.solr.mcp.server.config; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.mcp.server.TestcontainersConfiguration; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; +import org.testcontainers.containers.SolrContainer; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +@Import(TestcontainersConfiguration.class) +class SolrConfigTest { + + @Autowired + SolrContainer solrContainer; + @Autowired + private SolrClient solrClient; + @Autowired + private SolrConfigurationProperties properties; + + @Test + void testSolrClientConfiguration() { + // Verify that the SolrClient is properly configured + assertNotNull(solrClient); + + // Verify that the SolrClient is using the correct URL + // Note: SolrConfig normalizes the URL to have trailing slash, but Http2SolrClient removes + // it + var httpSolrClient = assertInstanceOf(Http2SolrClient.class, solrClient); + String expectedUrl = + "http://" + + solrContainer.getHost() + + ":" + + solrContainer.getMappedPort(8983) + + "/solr"; + assertEquals(expectedUrl, httpSolrClient.getBaseURL()); + } + + @Test + void testSolrConfigurationProperties() { + // Verify that the properties are correctly loaded + assertNotNull(properties); + assertNotNull(properties.url()); + assertEquals( + "http://" + + solrContainer.getHost() + + ":" + + solrContainer.getMappedPort(8983) + + "/solr/", + properties.url()); + } + + @ParameterizedTest + @CsvSource({ + "http://localhost:8983, http://localhost:8983/solr", + "http://localhost:8983/, http://localhost:8983/solr", + "http://localhost:8983/solr, http://localhost:8983/solr", + "http://localhost:8983/solr/, http://localhost:8983/solr", + "http://localhost:8983/custom/solr/, http://localhost:8983/custom/solr" + }) + void testUrlNormalization(String inputUrl, String expectedUrl) { + // Create a test properties object + SolrConfigurationProperties testProperties = new SolrConfigurationProperties(inputUrl); + + // Create SolrConfig instance + SolrConfig solrConfig = new SolrConfig(); + + // Test URL normalization + SolrClient client = solrConfig.solrClient(testProperties); + assertNotNull(client); + + var httpClient = assertInstanceOf(Http2SolrClient.class, client); + assertEquals(expectedUrl, httpClient.getBaseURL()); + + // Clean up + try { + client.close(); + } catch (Exception _) { + // Ignore close errors in test + } + } + + @Test + void testUrlWithoutTrailingSlash() { + // Test URL without trailing slash branch + SolrConfigurationProperties testProperties = + new SolrConfigurationProperties("http://localhost:8983"); + SolrConfig solrConfig = new SolrConfig(); + + SolrClient client = solrConfig.solrClient(testProperties); + Http2SolrClient httpClient = (Http2SolrClient) client; + + // Should add trailing slash and solr path + assertEquals("http://localhost:8983/solr", httpClient.getBaseURL()); + + try { + client.close(); + } catch (Exception _) { + // Ignore close errors in test + } + } + + @Test + void testUrlWithTrailingSlashButNoSolrPath() { + // Test URL with trailing slash but no solr path branch + SolrConfigurationProperties testProperties = + new SolrConfigurationProperties("http://localhost:8983/"); + SolrConfig solrConfig = new SolrConfig(); + + SolrClient client = solrConfig.solrClient(testProperties); + Http2SolrClient httpClient = (Http2SolrClient) client; + + // Should add solr path to existing trailing slash + assertEquals("http://localhost:8983/solr", httpClient.getBaseURL()); + + try { + client.close(); + } catch (Exception _) { + // Ignore close errors in test + } + } + + @Test + void testUrlWithSolrPathButNoTrailingSlash() { + // Test URL with solr path but no trailing slash + SolrConfigurationProperties testProperties = + new SolrConfigurationProperties("http://localhost:8983/solr"); + SolrConfig solrConfig = new SolrConfig(); + + SolrClient client = solrConfig.solrClient(testProperties); + Http2SolrClient httpClient = (Http2SolrClient) client; + + // Should add trailing slash + assertEquals("http://localhost:8983/solr", httpClient.getBaseURL()); + + try { + client.close(); + } catch (Exception _) { + // Ignore close errors in test + } + } + + @Test + void testUrlAlreadyProperlyFormatted() { + // Test URL that's already properly formatted + SolrConfigurationProperties testProperties = + new SolrConfigurationProperties("http://localhost:8983/solr/"); + SolrConfig solrConfig = new SolrConfig(); + + SolrClient client = solrConfig.solrClient(testProperties); + Http2SolrClient httpClient = (Http2SolrClient) client; + + // Should remain unchanged + assertEquals("http://localhost:8983/solr", httpClient.getBaseURL()); + + try { + client.close(); + } catch (Exception _) { + // Ignore close errors in test + } + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/indexing/CsvIndexingTest.java b/src/test/java/org/apache/solr/mcp/server/indexing/CsvIndexingTest.java new file mode 100644 index 0000000..29cb907 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/indexing/CsvIndexingTest.java @@ -0,0 +1,140 @@ +package org.apache.solr.mcp.server.indexing; + +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.mcp.server.indexing.documentcreator.IndexingDocumentCreator; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test class for CSV indexing functionality in IndexingService. + * + *

This test verifies that the IndexingService can correctly parse CSV data and convert it into + * SolrInputDocument objects using the schema-less approach. + */ +@SpringBootTest +@TestPropertySource(locations = "classpath:application.properties") +class CsvIndexingTest { + + @Autowired + private IndexingDocumentCreator indexingDocumentCreator; + + @Test + void testCreateSchemalessDocumentsFromCsv() throws Exception { + // Given + + String csvData = + """ + id,cat,name,price,inStock,author,series_t,sequence_i,genre_s + 0553573403,book,A Game of Thrones,7.99,true,George R.R. Martin,"A Song of Ice and Fire",1,fantasy + 0553579908,book,A Clash of Kings,7.99,true,George R.R. Martin,"A Song of Ice and Fire",2,fantasy + 0553293354,book,Foundation,7.99,true,Isaac Asimov,Foundation Novels,1,scifi + """; + + // When + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromCsv(csvData); + + // Then + assertThat(documents).hasSize(3); + + // Verify first document + SolrInputDocument firstDoc = documents.getFirst(); + assertThat(firstDoc.getFieldValue("id")).isEqualTo("0553573403"); + assertThat(firstDoc.getFieldValue("cat")).isEqualTo("book"); + assertThat(firstDoc.getFieldValue("name")).isEqualTo("A Game of Thrones"); + assertThat(firstDoc.getFieldValue("price")).isEqualTo("7.99"); + assertThat(firstDoc.getFieldValue("instock")).isEqualTo("true"); + assertThat(firstDoc.getFieldValue("author")).isEqualTo("George R.R. Martin"); + assertThat(firstDoc.getFieldValue("series_t")).isEqualTo("A Song of Ice and Fire"); + assertThat(firstDoc.getFieldValue("sequence_i")).isEqualTo("1"); + assertThat(firstDoc.getFieldValue("genre_s")).isEqualTo("fantasy"); + + // Verify second document + SolrInputDocument secondDoc = documents.get(1); + assertThat(secondDoc.getFieldValue("id")).isEqualTo("0553579908"); + assertThat(secondDoc.getFieldValue("name")).isEqualTo("A Clash of Kings"); + assertThat(secondDoc.getFieldValue("sequence_i")).isEqualTo("2"); + + // Verify third document + SolrInputDocument thirdDoc = documents.get(2); + assertThat(thirdDoc.getFieldValue("id")).isEqualTo("0553293354"); + assertThat(thirdDoc.getFieldValue("name")).isEqualTo("Foundation"); + assertThat(thirdDoc.getFieldValue("author")).isEqualTo("Isaac Asimov"); + assertThat(thirdDoc.getFieldValue("genre_s")).isEqualTo("scifi"); + } + + @Test + void testCreateSchemalessDocumentsFromCsvWithEmptyValues() throws Exception { + // Given + + String csvData = + """ + id,name,description + 1,Test Product,Some description + 2,Another Product, + 3,,Empty name + """; + + // When + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromCsv(csvData); + + // Then + assertThat(documents).hasSize(3); + + // First document should have all fields + SolrInputDocument firstDoc = documents.getFirst(); + assertThat(firstDoc.getFieldValue("id")).isEqualTo("1"); + assertThat(firstDoc.getFieldValue("name")).isEqualTo("Test Product"); + assertThat(firstDoc.getFieldValue("description")).isEqualTo("Some description"); + + // Second document should skip empty description + SolrInputDocument secondDoc = documents.get(1); + assertThat(secondDoc.getFieldValue("id")).isEqualTo("2"); + assertThat(secondDoc.getFieldValue("name")).isEqualTo("Another Product"); + assertThat(secondDoc.getFieldValue("description")).isNull(); + + // Third document should skip empty name + SolrInputDocument thirdDoc = documents.get(2); + assertThat(thirdDoc.getFieldValue("id")).isEqualTo("3"); + assertThat(thirdDoc.getFieldValue("name")).isNull(); + assertThat(thirdDoc.getFieldValue("description")).isEqualTo("Empty name"); + } + + @Test + void testCreateSchemalessDocumentsFromCsvWithQuotedValues() throws Exception { + // Given + + String csvData = + """ + id,name,description + 1,"Quoted Name","Quoted description" + 2,Regular Name,Regular description + """; + + // When + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromCsv(csvData); + + // Then + assertThat(documents).hasSize(2); + + // First document should have quotes removed + SolrInputDocument firstDoc = documents.getFirst(); + assertThat(firstDoc.getFieldValue("id")).isEqualTo("1"); + assertThat(firstDoc.getFieldValue("name")).isEqualTo("Quoted Name"); + assertThat(firstDoc.getFieldValue("description")).isEqualTo("Quoted description"); + + // Second document should remain unchanged + SolrInputDocument secondDoc = documents.get(1); + assertThat(secondDoc.getFieldValue("id")).isEqualTo("2"); + assertThat(secondDoc.getFieldValue("name")).isEqualTo("Regular Name"); + assertThat(secondDoc.getFieldValue("description")).isEqualTo("Regular description"); + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/indexing/IndexingServiceDirectTest.java b/src/test/java/org/apache/solr/mcp/server/indexing/IndexingServiceDirectTest.java new file mode 100644 index 0000000..3a29264 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/indexing/IndexingServiceDirectTest.java @@ -0,0 +1,209 @@ +package org.apache.solr.mcp.server.indexing; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.response.UpdateResponse; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.mcp.server.indexing.documentcreator.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class IndexingServiceDirectTest { + + @Mock + private SolrClient solrClient; + + @Mock + private UpdateResponse updateResponse; + + private IndexingService indexingService; + private IndexingDocumentCreator indexingDocumentCreator; + + @BeforeEach + void setUp() { + indexingDocumentCreator = + new IndexingDocumentCreator( + new XmlDocumentCreator(), + new CsvDocumentCreator(), + new JsonDocumentCreator()); + indexingService = new IndexingService(solrClient, indexingDocumentCreator); + } + + @Test + void testBatchIndexingErrorHandling() throws Exception { + // Create a list of test documents + List documents = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + SolrInputDocument doc = new SolrInputDocument(); + doc.addField("id", "test" + i); + doc.addField("title", "Test Document " + i); + documents.add(doc); + } + + // Mock behavior: Batch add fails, but individual adds succeed + when(solrClient.add(anyString(), anyList())) + .thenThrow(new RuntimeException("Batch indexing failed")); + + // Individual document adds should succeed + when(solrClient.add(anyString(), any(SolrInputDocument.class))).thenReturn(updateResponse); + + // Call the method under test + int successCount = indexingService.indexDocuments("test_collection", documents); + + // Verify the results + assertEquals(10, successCount, "All documents should be successfully indexed individually"); + + // Verify that batch add was attempted once + verify(solrClient, times(1)).add(eq("test_collection"), anyList()); + + // Verify that individual adds were attempted for each document + verify(solrClient, times(10)).add(eq("test_collection"), any(SolrInputDocument.class)); + + // Verify that commit was called + verify(solrClient, times(1)).commit("test_collection"); + } + + @Test + void testBatchIndexingPartialFailure() throws Exception { + // Create a list of test documents + List documents = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + SolrInputDocument doc = new SolrInputDocument(); + doc.addField("id", "test" + i); + doc.addField("title", "Test Document " + i); + documents.add(doc); + } + + // Mock behavior: Batch add fails + when(solrClient.add(anyString(), anyList())) + .thenThrow(new RuntimeException("Batch indexing failed")); + + // Even-numbered documents succeed, odd-numbered documents fail + for (int i = 0; i < 10; i++) { + if (i % 2 == 0) { + when(solrClient.add("test_collection", documents.get(i))) + .thenReturn(updateResponse); + } else { + when(solrClient.add("test_collection", documents.get(i))) + .thenThrow(new RuntimeException("Document " + i + " indexing failed")); + } + } + + // Call the method under test + int successCount = indexingService.indexDocuments("test_collection", documents); + + // Verify the results - only even-numbered documents should succeed + assertEquals(5, successCount, "Only half of the documents should be successfully indexed"); + + // Verify that batch add was attempted once + verify(solrClient, times(1)).add(eq("test_collection"), anyList()); + + // Verify that individual adds were attempted for each document + verify(solrClient, times(10)).add(eq("test_collection"), any(SolrInputDocument.class)); + + // Verify that commit was called + verify(solrClient, times(1)).commit("test_collection"); + } + + @Test + void testIndexJsonDocumentsWithJsonString() throws Exception { + // Test JSON string with multiple documents + String json = + """ + [ + { + "id": "test001", + "title": "Test Document 1", + "content": "This is test content 1" + }, + { + "id": "test002", + "title": "Test Document 2", + "content": "This is test content 2" + } + ] + """; + + // Create a spy on the indexingDocumentCreator and inject it into a new IndexingService + IndexingDocumentCreator indexingDocumentCreatorSpy = spy(indexingDocumentCreator); + IndexingService indexingServiceWithSpy = + new IndexingService(solrClient, indexingDocumentCreatorSpy); + IndexingService indexingServiceSpy = spy(indexingServiceWithSpy); + + // Create mock documents that would be returned by createSchemalessDocuments + List mockDocuments = new ArrayList<>(); + SolrInputDocument doc1 = new SolrInputDocument(); + doc1.addField("id", "test001"); + doc1.addField("title", "Test Document 1"); + doc1.addField("content", "This is test content 1"); + + SolrInputDocument doc2 = new SolrInputDocument(); + doc2.addField("id", "test002"); + doc2.addField("title", "Test Document 2"); + doc2.addField("content", "This is test content 2"); + + mockDocuments.add(doc1); + mockDocuments.add(doc2); + + // Mock the createSchemalessDocuments method to return our mock documents + doReturn(mockDocuments) + .when(indexingDocumentCreatorSpy) + .createSchemalessDocumentsFromJson(json); + + // Mock the indexDocuments method that takes a collection and list of documents + doReturn(2).when(indexingServiceSpy).indexDocuments(anyString(), anyList()); + + // Call the method under test + indexingServiceSpy.indexJsonDocuments("test_collection", json); + + // Verify that createSchemalessDocuments was called with the JSON string + verify(indexingDocumentCreatorSpy, times(1)).createSchemalessDocumentsFromJson(json); + + // Verify that indexDocuments was called with the collection name and the documents + verify(indexingServiceSpy, times(1)).indexDocuments("test_collection", mockDocuments); + } + + @Test + void testIndexJsonDocumentsWithJsonStringErrorHandling() throws Exception { + // Test JSON string with invalid format + String invalidJson = "{ This is not valid JSON }"; + + // Create a spy on the indexingDocumentCreator and inject it into a new IndexingService + IndexingDocumentCreator indexingDocumentCreatorSpy = spy(indexingDocumentCreator); + IndexingService indexingServiceWithSpy = + new IndexingService(solrClient, indexingDocumentCreatorSpy); + IndexingService indexingServiceSpy = spy(indexingServiceWithSpy); + + // Mock the createSchemalessDocuments method to throw an exception + doThrow(new DocumentProcessingException("Invalid JSON")) + .when(indexingDocumentCreatorSpy) + .createSchemalessDocumentsFromJson(invalidJson); + + // Call the method under test and verify it throws an exception + DocumentProcessingException exception = + assertThrows( + DocumentProcessingException.class, + () -> { + indexingServiceSpy.indexJsonDocuments("test_collection", invalidJson); + }); + + // Verify the exception message + assertTrue(exception.getMessage().contains("Invalid JSON")); + + // Verify that createSchemalessDocuments was called + verify(indexingDocumentCreatorSpy, times(1)).createSchemalessDocumentsFromJson(invalidJson); + + // Verify that indexDocuments with documents was not called + verify(indexingServiceSpy, never()).indexDocuments(anyString(), anyList()); + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/indexing/IndexingServiceTest.java b/src/test/java/org/apache/solr/mcp/server/indexing/IndexingServiceTest.java new file mode 100644 index 0000000..8dbf3f7 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/indexing/IndexingServiceTest.java @@ -0,0 +1,1084 @@ +package org.apache.solr.mcp.server.indexing; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.request.CollectionAdminRequest; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.mcp.server.TestcontainersConfiguration; +import org.apache.solr.mcp.server.indexing.documentcreator.CsvDocumentCreator; +import org.apache.solr.mcp.server.indexing.documentcreator.IndexingDocumentCreator; +import org.apache.solr.mcp.server.indexing.documentcreator.JsonDocumentCreator; +import org.apache.solr.mcp.server.indexing.documentcreator.XmlDocumentCreator; +import org.apache.solr.mcp.server.search.SearchResponse; +import org.apache.solr.mcp.server.search.SearchService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; +import org.testcontainers.containers.SolrContainer; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +@SpringBootTest +@Import(TestcontainersConfiguration.class) +class IndexingServiceTest { + + private static final String COLLECTION_NAME = "indexing_test_" + System.currentTimeMillis(); + private static boolean initialized = false; + @Autowired + private SolrContainer solrContainer; + @Autowired + private IndexingDocumentCreator indexingDocumentCreator; + @Autowired + private IndexingService indexingService; + @Autowired + private SearchService searchService; + @Autowired + private SolrClient solrClient; + + @BeforeEach + void setUp() throws Exception { + + // Create processor instances and wire them manually since this is not a Spring Boot test + XmlDocumentCreator xmlDocumentCreator = new XmlDocumentCreator(); + CsvDocumentCreator csvDocumentCreator = new CsvDocumentCreator(); + JsonDocumentCreator jsonDocumentCreator = new JsonDocumentCreator(); + + indexingDocumentCreator = + new IndexingDocumentCreator( + xmlDocumentCreator, csvDocumentCreator, jsonDocumentCreator); + + indexingService = new IndexingService(solrClient, indexingDocumentCreator); + searchService = new SearchService(solrClient); + + if (!initialized) { + // Create collection + CollectionAdminRequest.Create createRequest = + CollectionAdminRequest.createCollection(COLLECTION_NAME, "_default", 1, 1); + createRequest.process(solrClient); + initialized = true; + } + } + + @Test + void testCreateSchemalessDocumentsFromJson() throws Exception { + // Test JSON string + String json = + """ + [ + { + "id": "test001", + "cat": ["book"], + "name": ["Test Book 1"], + "price": [9.99], + "inStock": [true], + "author": ["Test Author"], + "series_t": "Test Series", + "sequence_i": 1, + "genre_s": "test" + } + ] + """; + + // Create documents + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromJson(json); + + // Verify documents were created correctly + assertNotNull(documents); + assertEquals(1, documents.size()); + + SolrInputDocument doc = documents.getFirst(); + assertEquals("test001", doc.getFieldValue("id")); + + // Check field values - they might be stored directly or as collections + Object nameValue = doc.getFieldValue("name"); + if (nameValue instanceof List) { + assertEquals("Test Book 1", ((List) nameValue).getFirst()); + } else { + assertEquals("Test Book 1", nameValue); + } + + Object priceValue = doc.getFieldValue("price"); + if (priceValue instanceof List) { + assertEquals(9.99, ((List) priceValue).getFirst()); + } else { + assertEquals(9.99, priceValue); + } + + Object inStockValue = doc.getFieldValue("inStock"); + // Check if inStock field exists + if (inStockValue != null) { + if (inStockValue instanceof List) { + assertEquals(true, ((List) inStockValue).getFirst()); + } else { + assertEquals(true, inStockValue); + } + } else { + // If inStock is not present in the document, we'll skip this assertion + // Removed debug print statement + } + + Object authorValue = doc.getFieldValue("author"); + if (authorValue instanceof List) { + assertEquals("Test Author", ((List) authorValue).getFirst()); + } else { + assertEquals("Test Author", authorValue); + } + + assertEquals("Test Series", doc.getFieldValue("series_t")); + assertEquals(1, doc.getFieldValue("sequence_i")); + assertEquals("test", doc.getFieldValue("genre_s")); + } + + @Test + void testIndexJsonDocuments() throws Exception { + + // Test JSON string with multiple documents + String json = + """ + [ + { + "id": "test002", + "cat": ["book"], + "name": ["Test Book 2"], + "price": [19.99], + "inStock": [true], + "author": ["Test Author 2"], + "genre_s": "scifi" + }, + { + "id": "test003", + "cat": ["book"], + "name": ["Test Book 3"], + "price": [29.99], + "inStock": [false], + "author": ["Test Author 3"], + "genre_s": "fantasy" + } + ] + """; + + // Index documents + indexingService.indexJsonDocuments(COLLECTION_NAME, json); + + // Verify documents were indexed by searching for them + SearchResponse result = + searchService.search( + COLLECTION_NAME, "id:test002 OR id:test003", null, null, null, null, null); + + assertNotNull(result); + List> documents = result.documents(); + assertEquals(2, documents.size()); + + // Verify specific document fields + boolean foundBook2 = false; + boolean foundBook3 = false; + + for (Map book : documents) { + // Get ID and handle both String and List cases + Object idValue = book.get("id"); + String id; + if (idValue instanceof List) { + id = (String) ((List) idValue).getFirst(); + } else { + id = (String) idValue; + } + + if (id.equals("test002")) { + foundBook2 = true; + + // Handle name field + Object nameValue = book.get("name"); + if (nameValue instanceof List) { + assertEquals("Test Book 2", ((List) nameValue).getFirst()); + } else { + assertEquals("Test Book 2", nameValue); + } + + // Handle author field + Object authorValue = book.get("author"); + if (authorValue instanceof List) { + assertEquals("Test Author 2", ((List) authorValue).getFirst()); + } else { + assertEquals("Test Author 2", authorValue); + } + + // Handle genre field + Object genreValue = book.get("genre_s"); + if (genreValue instanceof List) { + assertEquals("scifi", ((List) genreValue).getFirst()); + } else { + assertEquals("scifi", genreValue); + } + } else if (id.equals("test003")) { + foundBook3 = true; + + // Handle name field + Object nameValue = book.get("name"); + if (nameValue instanceof List) { + assertEquals("Test Book 3", ((List) nameValue).getFirst()); + } else { + assertEquals("Test Book 3", nameValue); + } + + // Handle author field + Object authorValue = book.get("author"); + if (authorValue instanceof List) { + assertEquals("Test Author 3", ((List) authorValue).getFirst()); + } else { + assertEquals("Test Author 3", authorValue); + } + + // Handle genre field + Object genreValue = book.get("genre_s"); + if (genreValue instanceof List) { + assertEquals("fantasy", ((List) genreValue).getFirst()); + } else { + assertEquals("fantasy", genreValue); + } + } + } + + assertTrue(foundBook2, "Book 2 should be found in search results"); + assertTrue(foundBook3, "Book 3 should be found in search results"); + } + + @Test + void testIndexJsonDocumentsWithNestedObjects() throws Exception { + + // Test JSON string with nested objects + String json = + """ + [ + { + "id": "test004", + "cat": ["book"], + "name": ["Test Book 4"], + "price": [39.99], + "details": { + "publisher": "Test Publisher", + "year": 2023, + "edition": 1 + }, + "author": ["Test Author 4"] + } + ] + """; + + // Index documents + indexingService.indexJsonDocuments(COLLECTION_NAME, json); + + // Verify documents were indexed by searching for them + SearchResponse result = + searchService.search(COLLECTION_NAME, "id:test004", null, null, null, null, null); + + assertNotNull(result); + List> documents = result.documents(); + assertEquals(1, documents.size()); + + Map book = documents.getFirst(); + + // Handle ID field + Object idValue = book.get("id"); + if (idValue instanceof List) { + assertEquals("test004", ((List) idValue).getFirst()); + } else { + assertEquals("test004", idValue); + } + + // Handle name field + Object nameValue = book.get("name"); + if (nameValue instanceof List) { + assertEquals("Test Book 4", ((List) nameValue).getFirst()); + } else { + assertEquals("Test Book 4", nameValue); + } + + // Check that nested fields were flattened with underscore prefix + assertNotNull(book.get("details_publisher")); + Object publisherValue = book.get("details_publisher"); + if (publisherValue instanceof List) { + assertEquals("Test Publisher", ((List) publisherValue).getFirst()); + } else { + assertEquals("Test Publisher", publisherValue); + } + + assertNotNull(book.get("details_year")); + Object yearValue = book.get("details_year"); + if (yearValue instanceof List) { + assertEquals(2023, ((Number) ((List) yearValue).getFirst()).intValue()); + } else if (yearValue instanceof Number) { + assertEquals(2023, ((Number) yearValue).intValue()); + } else { + assertEquals("2023", yearValue.toString()); + } + } + + @Test + void testSanitizeFieldName() throws Exception { + + // Test JSON string with field names that need sanitizing + String json = + """ + [ + { + "id": "test005", + "invalid-field": "Value with hyphen", + "another.invalid": "Value with dot", + "UPPERCASE": "Value with uppercase", + "multiple__underscores": "Value with multiple underscores" + } + ] + """; + + // Index documents + indexingService.indexJsonDocuments(COLLECTION_NAME, json); + + // Verify documents were indexed with sanitized field names + SearchResponse result = + searchService.search(COLLECTION_NAME, "id:test005", null, null, null, null, null); + + assertNotNull(result); + List> documents = result.documents(); + assertEquals(1, documents.size()); + + Map doc = documents.getFirst(); + + // Check that field names were sanitized + assertNotNull(doc.get("invalid_field")); + Object invalidFieldValue = doc.get("invalid_field"); + if (invalidFieldValue instanceof List) { + assertEquals("Value with hyphen", ((List) invalidFieldValue).getFirst()); + } else { + assertEquals("Value with hyphen", invalidFieldValue); + } + + assertNotNull(doc.get("another_invalid")); + Object anotherInvalidValue = doc.get("another_invalid"); + if (anotherInvalidValue instanceof List) { + assertEquals("Value with dot", ((List) anotherInvalidValue).getFirst()); + } else { + assertEquals("Value with dot", anotherInvalidValue); + } + + // Should be lowercase + assertNotNull(doc.get("uppercase")); + Object uppercaseValue = doc.get("uppercase"); + if (uppercaseValue instanceof List) { + assertEquals("Value with uppercase", ((List) uppercaseValue).getFirst()); + } else { + assertEquals("Value with uppercase", uppercaseValue); + } + + // Multiple underscores should be collapsed + assertNotNull(doc.get("multiple_underscores")); + Object multipleUnderscoresValue = doc.get("multiple_underscores"); + if (multipleUnderscoresValue instanceof List) { + assertEquals( + "Value with multiple underscores", + ((List) multipleUnderscoresValue).getFirst()); + } else { + assertEquals("Value with multiple underscores", multipleUnderscoresValue); + } + } + + @Test + void testDeeplyNestedJsonStructures() throws Exception { + + // Test JSON string with deeply nested objects (3+ levels) + String json = + """ + [ + { + "id": "nested001", + "title": "Deeply nested document", + "metadata": { + "publication": { + "publisher": { + "name": "Deep Nest Publishing", + "location": { + "city": "Nestville", + "country": "Nestland", + "coordinates": { + "latitude": 42.123, + "longitude": -71.456 + } + } + }, + "year": 2023, + "edition": { + "number": 1, + "type": "First Edition", + "notes": { + "condition": "New", + "availability": "Limited" + } + } + }, + "classification": { + "primary": "Test", + "secondary": { + "category": "Nested", + "subcategory": "Deep" + } + } + } + } + ] + """; + + // Index documents + indexingService.indexJsonDocuments(COLLECTION_NAME, json); + + // Verify documents were indexed by searching for them + SearchResponse result = + searchService.search(COLLECTION_NAME, "id:nested001", null, null, null, null, null); + + assertNotNull(result); + List> documents = result.documents(); + assertEquals(1, documents.size()); + + Map doc = documents.getFirst(); + + // Check that deeply nested fields were flattened with underscore prefix + // Level 1 + assertNotNull(doc.get("metadata_publication_publisher_name")); + assertEquals( + "Deep Nest Publishing", getFieldValue(doc, "metadata_publication_publisher_name")); + + // Level 2 + assertNotNull(doc.get("metadata_publication_publisher_location_city")); + assertEquals( + "Nestville", getFieldValue(doc, "metadata_publication_publisher_location_city")); + + // Level 3 + assertNotNull(doc.get("metadata_publication_publisher_location_coordinates_latitude")); + assertEquals( + 42.123, + ((Number) + getFieldValue( + doc, + "metadata_publication_publisher_location_coordinates_latitude")) + .doubleValue(), + 0.001); + + // Check other branches of the nested structure + assertNotNull(doc.get("metadata_publication_edition_notes_condition")); + assertEquals("New", getFieldValue(doc, "metadata_publication_edition_notes_condition")); + + assertNotNull(doc.get("metadata_classification_secondary_subcategory")); + assertEquals("Deep", getFieldValue(doc, "metadata_classification_secondary_subcategory")); + } + + private Object getFieldValue(Map doc, String fieldName) { + Object value = doc.get(fieldName); + if (value instanceof List) { + return ((List) value).getFirst(); + } + return value; + } + + @Test + void testSpecialCharactersInFieldNames() throws Exception { + + // Test JSON string with field names containing various special characters + String json = + """ + [ + { + "id": "special_fields_001", + "field@with@at": "Value with @ symbols", + "field#with#hash": "Value with # symbols", + "field$with$dollar": "Value with $ symbols", + "field%with%percent": "Value with % symbols", + "field^with^caret": "Value with ^ symbols", + "field&with&ersand": "Value with & symbols", + "field*with*asterisk": "Value with * symbols", + "field(with)parentheses": "Value with parentheses", + "field[with]brackets": "Value with brackets", + "field{with}braces": "Value with braces", + "field+with+plus": "Value with + symbols", + "field=with=equals": "Value with = symbols", + "field:with:colon": "Value with : symbols", + "field;with;semicolon": "Value with ; symbols", + "field'with'quotes": "Value with ' symbols", + "field\\"with\\"doublequotes": "Value with \\" symbols", + "fieldanglebrackets": "Value with angle brackets", + "field,with,commas": "Value with , symbols", + "field?with?question": "Value with ? symbols", + "field/with/slashes": "Value with / symbols", + "field\\\\with\\\\backslashes": "Value with \\\\ symbols", + "field|with|pipes": "Value with | symbols", + "field`with`backticks": "Value with ` symbols", + "field~with~tildes": "Value with ~ symbols" + } + ] + """; + + // Index documents + indexingService.indexJsonDocuments(COLLECTION_NAME, json); + + // Verify documents were indexed by searching for them + SearchResponse result = + searchService.search( + COLLECTION_NAME, "id:special_fields_001", null, null, null, null, null); + + assertNotNull(result); + List> documents = result.documents(); + assertEquals(1, documents.size()); + + Map doc = documents.getFirst(); + + // Check that field names with special characters were sanitized + // All special characters should be replaced with underscores + assertNotNull(doc.get("field_with_at")); + assertEquals("Value with @ symbols", getFieldValue(doc, "field_with_at")); + + assertNotNull(doc.get("field_with_hash")); + assertEquals("Value with # symbols", getFieldValue(doc, "field_with_hash")); + + assertNotNull(doc.get("field_with_dollar")); + assertEquals("Value with $ symbols", getFieldValue(doc, "field_with_dollar")); + + assertNotNull(doc.get("field_with_percent")); + assertEquals("Value with % symbols", getFieldValue(doc, "field_with_percent")); + + assertNotNull(doc.get("field_with_caret")); + assertEquals("Value with ^ symbols", getFieldValue(doc, "field_with_caret")); + + assertNotNull(doc.get("field_with_ampersand")); + assertEquals("Value with & symbols", getFieldValue(doc, "field_with_ampersand")); + + assertNotNull(doc.get("field_with_asterisk")); + assertEquals("Value with * symbols", getFieldValue(doc, "field_with_asterisk")); + + assertNotNull(doc.get("field_with_parentheses")); + assertEquals("Value with parentheses", getFieldValue(doc, "field_with_parentheses")); + + assertNotNull(doc.get("field_with_brackets")); + assertEquals("Value with brackets", getFieldValue(doc, "field_with_brackets")); + + assertNotNull(doc.get("field_with_braces")); + assertEquals("Value with braces", getFieldValue(doc, "field_with_braces")); + } + + @Test + void testArraysOfObjects() throws Exception { + + // Test JSON string with arrays of objects + String json = + """ + [ + { + "id": "array_objects_001", + "title": "Document with arrays of objects", + "authors": [ + { + "name": "Author One", + "email": "author1@example.com", + "affiliation": "University A" + }, + { + "name": "Author Two", + "email": "author2@example.com", + "affiliation": "University B" + } + ], + "reviews": [ + { + "reviewer": "Reviewer A", + "rating": 4, + "comments": "Good document" + }, + { + "reviewer": "Reviewer B", + "rating": 5, + "comments": "Excellent document" + }, + { + "reviewer": "Reviewer C", + "rating": 3, + "comments": "Average document" + } + ], + "keywords": ["arrays", "objects", "testing"] + } + ] + """; + + // Index documents + indexingService.indexJsonDocuments(COLLECTION_NAME, json); + + // Verify documents were indexed by searching for them + SearchResponse result = + searchService.search( + COLLECTION_NAME, "id:array_objects_001", null, null, null, null, null); + + assertNotNull(result); + List> documents = result.documents(); + assertEquals(1, documents.size()); + + Map doc = documents.getFirst(); + + // Check that the document was indexed correctly + assertEquals("array_objects_001", getFieldValue(doc, "id")); + assertEquals("Document with arrays of objects", getFieldValue(doc, "title")); + + // Check that the arrays of primitive values were indexed correctly + Object keywordsObj = doc.get("keywords"); + if (keywordsObj instanceof List) { + List keywords = (List) keywordsObj; + assertEquals(3, keywords.size()); + assertTrue(keywords.contains("arrays")); + assertTrue(keywords.contains("objects")); + assertTrue(keywords.contains("testing")); + } + + // For arrays of objects, the IndexingService should flatten them with field names + // that include the array name and the object field name + // We can't directly access the array elements, but we can check if the flattened fields + // exist + + // Check for flattened author fields + // Note: The current implementation in IndexingService.java doesn't handle arrays of objects + // in a way that preserves the array structure. It skips object items in arrays (line + // 68-70). + // This test is checking the current behavior, which may need improvement in the future. + + // Check for flattened review fields + // Same note as above applies here + } + + @Test + void testNonArrayJsonInput() throws Exception { + // Test JSON string that is not an array but a single object + String json = + """ + { + "id": "single_object_001", + "title": "Single Object Document", + "author": "Test Author", + "year": 2023 + } + """; + + // Create documents + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromJson(json); + + // Verify no documents were created since input is not an array + assertNotNull(documents); + assertEquals(0, documents.size()); + } + + @Test + void testConvertJsonValueTypes() throws Exception { + // Test JSON with different value types + String json = + """ + [ + { + "id": "value_types_001", + "boolean_value": true, + "int_value": 42, + "double_value": 3.14159, + "long_value": 9223372036854775807, + "text_value": "This is a text value" + } + ] + """; + + // Create documents + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromJson(json); + + // Verify documents were created correctly + assertNotNull(documents); + assertEquals(1, documents.size()); + + SolrInputDocument doc = documents.getFirst(); + assertEquals("value_types_001", doc.getFieldValue("id")); + + // Verify each value type was converted correctly + assertEquals(true, doc.getFieldValue("boolean_value")); + assertEquals(42, doc.getFieldValue("int_value")); + assertEquals(3.14159, doc.getFieldValue("double_value")); + assertEquals(9223372036854775807L, doc.getFieldValue("long_value")); + assertEquals("This is a text value", doc.getFieldValue("text_value")); + } + + @Test + void testDirectSanitizeFieldName() throws Exception { + // Test sanitizing field names directly + // Create a document with field names that need sanitizing + String json = + """ + [ + { + "id": "field_names_001", + "field-with-hyphens": "Value 1", + "field.with.dots": "Value 2", + "field with spaces": "Value 3", + "UPPERCASE_FIELD": "Value 4", + "__leading_underscores__": "Value 5", + "trailing_underscores___": "Value 6", + "multiple___underscores": "Value 7" + } + ] + """; + + // Create documents + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromJson(json); + + // Verify documents were created correctly + assertNotNull(documents); + assertEquals(1, documents.size()); + + SolrInputDocument doc = documents.getFirst(); + + // Verify field names were sanitized correctly + assertEquals("field_names_001", doc.getFieldValue("id")); + assertEquals("Value 1", doc.getFieldValue("field_with_hyphens")); + assertEquals("Value 2", doc.getFieldValue("field_with_dots")); + assertEquals("Value 3", doc.getFieldValue("field_with_spaces")); + assertEquals("Value 4", doc.getFieldValue("uppercase_field")); + assertEquals("Value 5", doc.getFieldValue("leading_underscores")); + assertEquals("Value 6", doc.getFieldValue("trailing_underscores")); + assertEquals("Value 7", doc.getFieldValue("multiple_underscores")); + } +} + +@Nested +@ExtendWith(MockitoExtension.class) +class UnitTests { + + @Mock + private SolrClient solrClient; + + @Mock + private IndexingDocumentCreator indexingDocumentCreator; + + private IndexingService indexingService; + + @BeforeEach + void setUp() { + indexingService = new IndexingService(solrClient, indexingDocumentCreator); + } + + @Test + void constructor_ShouldInitializeWithDependencies() { + assertNotNull(indexingService); + } + + @Test + void indexJsonDocuments_WithValidJson_ShouldIndexDocuments() throws Exception { + String json = "[{\"id\":\"1\",\"title\":\"Test\"}]"; + List mockDocs = createMockDocuments(1); + when(indexingDocumentCreator.createSchemalessDocumentsFromJson(json)).thenReturn(mockDocs); + when(solrClient.add(eq("test_collection"), any(Collection.class))).thenReturn(null); + when(solrClient.commit("test_collection")).thenReturn(null); + + indexingService.indexJsonDocuments("test_collection", json); + + verify(indexingDocumentCreator).createSchemalessDocumentsFromJson(json); + verify(solrClient).add(eq("test_collection"), any(Collection.class)); + verify(solrClient).commit("test_collection"); + } + + @Test + void indexJsonDocuments_WhenDocumentCreatorThrowsException_ShouldPropagateException() + throws Exception { + String invalidJson = "not valid json"; + when(indexingDocumentCreator.createSchemalessDocumentsFromJson(invalidJson)) + .thenThrow( + new org.apache.solr.mcp.server.indexing.documentcreator + .DocumentProcessingException("Invalid JSON")); + + assertThrows( + org.apache.solr.mcp.server.indexing.documentcreator.DocumentProcessingException + .class, + () -> { + indexingService.indexJsonDocuments("test_collection", invalidJson); + }); + verify(solrClient, never()).add(anyString(), any(Collection.class)); + verify(solrClient, never()).commit(anyString()); + } + + @Test + void indexCsvDocuments_WithValidCsv_ShouldIndexDocuments() throws Exception { + String csv = "id,title\n1,Test\n2,Test2"; + List mockDocs = createMockDocuments(2); + when(indexingDocumentCreator.createSchemalessDocumentsFromCsv(csv)).thenReturn(mockDocs); + when(solrClient.add(eq("test_collection"), any(Collection.class))).thenReturn(null); + when(solrClient.commit("test_collection")).thenReturn(null); + + indexingService.indexCsvDocuments("test_collection", csv); + + verify(indexingDocumentCreator).createSchemalessDocumentsFromCsv(csv); + verify(solrClient).add(eq("test_collection"), any(Collection.class)); + verify(solrClient).commit("test_collection"); + } + + @Test + void indexCsvDocuments_WhenDocumentCreatorThrowsException_ShouldPropagateException() + throws Exception { + String invalidCsv = "malformed csv data"; + when(indexingDocumentCreator.createSchemalessDocumentsFromCsv(invalidCsv)) + .thenThrow( + new org.apache.solr.mcp.server.indexing.documentcreator + .DocumentProcessingException("Invalid CSV")); + + assertThrows( + org.apache.solr.mcp.server.indexing.documentcreator.DocumentProcessingException + .class, + () -> { + indexingService.indexCsvDocuments("test_collection", invalidCsv); + }); + verify(solrClient, never()).add(anyString(), any(Collection.class)); + verify(solrClient, never()).commit(anyString()); + } + + @Test + void indexXmlDocuments_WithValidXml_ShouldIndexDocuments() throws Exception { + String xml = "1Test"; + List mockDocs = createMockDocuments(1); + when(indexingDocumentCreator.createSchemalessDocumentsFromXml(xml)).thenReturn(mockDocs); + when(solrClient.add(eq("test_collection"), any(Collection.class))).thenReturn(null); + when(solrClient.commit("test_collection")).thenReturn(null); + + indexingService.indexXmlDocuments("test_collection", xml); + + verify(indexingDocumentCreator).createSchemalessDocumentsFromXml(xml); + verify(solrClient).add(eq("test_collection"), any(Collection.class)); + verify(solrClient).commit("test_collection"); + } + + @Test + void indexXmlDocuments_WhenParserConfigurationFails_ShouldPropagateException() + throws Exception { + String xml = "xml"; + when(indexingDocumentCreator.createSchemalessDocumentsFromXml(xml)) + .thenThrow( + new org.apache.solr.mcp.server.indexing.documentcreator + .DocumentProcessingException("Parser error")); + + assertThrows( + org.apache.solr.mcp.server.indexing.documentcreator.DocumentProcessingException + .class, + () -> { + indexingService.indexXmlDocuments("test_collection", xml); + }); + verify(solrClient, never()).add(anyString(), any(Collection.class)); + verify(solrClient, never()).commit(anyString()); + } + + @Test + void indexXmlDocuments_WhenSaxExceptionOccurs_ShouldPropagateException() throws Exception { + String xml = ""; + when(indexingDocumentCreator.createSchemalessDocumentsFromXml(xml)) + .thenThrow( + new org.apache.solr.mcp.server.indexing.documentcreator + .DocumentProcessingException("SAX parsing error")); + + assertThrows( + org.apache.solr.mcp.server.indexing.documentcreator.DocumentProcessingException + .class, + () -> { + indexingService.indexXmlDocuments("test_collection", xml); + }); + verify(solrClient, never()).add(anyString(), any(Collection.class)); + verify(solrClient, never()).commit(anyString()); + } + + @Test + void indexDocuments_WithSmallBatch_ShouldIndexSuccessfully() throws Exception { + List docs = createMockDocuments(5); + when(solrClient.add(eq("test_collection"), any(Collection.class))).thenReturn(null); + when(solrClient.commit("test_collection")).thenReturn(null); + + int result = indexingService.indexDocuments("test_collection", docs); + + assertEquals(5, result); + verify(solrClient).add(eq("test_collection"), any(Collection.class)); + verify(solrClient).commit("test_collection"); + } + + @Test + void indexDocuments_WithLargeBatch_ShouldProcessInBatches() throws Exception { + List docs = createMockDocuments(2500); + when(solrClient.add(eq("test_collection"), any(Collection.class))).thenReturn(null); + when(solrClient.commit("test_collection")).thenReturn(null); + + int result = indexingService.indexDocuments("test_collection", docs); + + assertEquals(2500, result); + verify(solrClient, times(3)).add(eq("test_collection"), any(Collection.class)); + verify(solrClient).commit("test_collection"); + } + + @Test + void indexDocuments_WhenBatchFails_ShouldRetryIndividually() throws Exception { + List docs = createMockDocuments(3); + + when(solrClient.add(eq("test_collection"), any(List.class))) + .thenThrow(new SolrServerException("Batch error")); + + when(solrClient.add(eq("test_collection"), any(SolrInputDocument.class))).thenReturn(null); + when(solrClient.commit("test_collection")).thenReturn(null); + + int result = indexingService.indexDocuments("test_collection", docs); + + assertEquals(3, result); + verify(solrClient).add(eq("test_collection"), any(Collection.class)); + verify(solrClient, times(3)).add(eq("test_collection"), any(SolrInputDocument.class)); + verify(solrClient).commit("test_collection"); + } + + @Test + void indexDocuments_WhenSomeIndividualDocumentsFail_ShouldIndexSuccessfulOnes() + throws Exception { + List docs = createMockDocuments(3); + + when(solrClient.add(eq("test_collection"), any(List.class))) + .thenThrow(new SolrServerException("Batch error")); + + when(solrClient.add(eq("test_collection"), any(SolrInputDocument.class))) + .thenReturn(null) + .thenThrow(new SolrServerException("Document error")) + .thenReturn(null); + + when(solrClient.commit("test_collection")).thenReturn(null); + + int result = indexingService.indexDocuments("test_collection", docs); + + assertEquals(2, result); + verify(solrClient).add(eq("test_collection"), any(Collection.class)); + verify(solrClient, times(3)).add(eq("test_collection"), any(SolrInputDocument.class)); + verify(solrClient).commit("test_collection"); + } + + @Test + void indexDocuments_WithEmptyList_ShouldStillCommit() throws Exception { + List emptyDocs = new ArrayList<>(); + when(solrClient.commit("test_collection")).thenReturn(null); + + int result = indexingService.indexDocuments("test_collection", emptyDocs); + + assertEquals(0, result); + verify(solrClient, never()).add(anyString(), any(List.class)); + verify(solrClient).commit("test_collection"); + } + + @Test + void indexDocuments_WhenCommitFails_ShouldPropagateException() throws Exception { + List docs = createMockDocuments(2); + when(solrClient.add(eq("test_collection"), any(Collection.class))).thenReturn(null); + when(solrClient.commit("test_collection")).thenThrow(new IOException("Commit failed")); + + assertThrows( + IOException.class, + () -> { + indexingService.indexDocuments("test_collection", docs); + }); + verify(solrClient).add(eq("test_collection"), any(Collection.class)); + verify(solrClient).commit("test_collection"); + } + + @Test + void indexDocuments_ShouldBatchCorrectly() throws Exception { + List docs = createMockDocuments(1000); + when(solrClient.add(eq("test_collection"), any(Collection.class))).thenReturn(null); + when(solrClient.commit("test_collection")).thenReturn(null); + + int result = indexingService.indexDocuments("test_collection", docs); + + assertEquals(1000, result); + + ArgumentCaptor> captor = + ArgumentCaptor.forClass(Collection.class); + verify(solrClient).add(eq("test_collection"), captor.capture()); + assertEquals(1000, captor.getValue().size()); + verify(solrClient).commit("test_collection"); + } + + @Test + void indexJsonDocuments_WhenSolrClientThrowsException_ShouldPropagateException() + throws Exception { + String json = "[{\"id\":\"1\"}]"; + List mockDocs = createMockDocuments(1); + when(indexingDocumentCreator.createSchemalessDocumentsFromJson(json)).thenReturn(mockDocs); + when(solrClient.add(eq("test_collection"), any(List.class))) + .thenThrow(new SolrServerException("Solr connection error")); + when(solrClient.add(eq("test_collection"), any(SolrInputDocument.class))) + .thenThrow(new SolrServerException("Solr connection error")); + when(solrClient.commit("test_collection")).thenReturn(null); + + indexingService.indexJsonDocuments("test_collection", json); + + verify(solrClient).add(eq("test_collection"), any(List.class)); + verify(solrClient).add(eq("test_collection"), any(SolrInputDocument.class)); + } + + @Test + void indexCsvDocuments_WhenSolrClientThrowsIOException_ShouldPropagateException() + throws Exception { + String csv = "id,title\n1,Test"; + List mockDocs = createMockDocuments(1); + when(indexingDocumentCreator.createSchemalessDocumentsFromCsv(csv)).thenReturn(mockDocs); + when(solrClient.add(eq("test_collection"), any(List.class))) + .thenThrow(new IOException("Network error")); + when(solrClient.add(eq("test_collection"), any(SolrInputDocument.class))) + .thenThrow(new IOException("Network error")); + when(solrClient.commit("test_collection")).thenReturn(null); + + indexingService.indexCsvDocuments("test_collection", csv); + + verify(solrClient).add(eq("test_collection"), any(List.class)); + verify(solrClient).add(eq("test_collection"), any(SolrInputDocument.class)); + } + + @Test + void indexDocuments_WithRuntimeException_ShouldRetryIndividually() throws Exception { + List docs = createMockDocuments(2); + + when(solrClient.add(eq("test_collection"), any(List.class))) + .thenThrow(new RuntimeException("Unexpected error")); + + when(solrClient.add(eq("test_collection"), any(SolrInputDocument.class))).thenReturn(null); + when(solrClient.commit("test_collection")).thenReturn(null); + + int result = indexingService.indexDocuments("test_collection", docs); + + assertEquals(2, result); + verify(solrClient).add(eq("test_collection"), any(Collection.class)); + verify(solrClient, times(2)).add(eq("test_collection"), any(SolrInputDocument.class)); + verify(solrClient).commit("test_collection"); + } + + private List createMockDocuments(int count) { + List docs = new ArrayList<>(); + for (int i = 0; i < count; i++) { + SolrInputDocument doc = new SolrInputDocument(); + doc.addField("id", "doc" + i); + doc.addField("title", "Document " + i); + docs.add(doc); + } + return docs; + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/indexing/XmlIndexingTest.java b/src/test/java/org/apache/solr/mcp/server/indexing/XmlIndexingTest.java new file mode 100644 index 0000000..dd32dc3 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/indexing/XmlIndexingTest.java @@ -0,0 +1,524 @@ +package org.apache.solr.mcp.server.indexing; + +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.mcp.server.indexing.documentcreator.IndexingDocumentCreator; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Test class for XML indexing functionality in IndexingService. + * + *

This test verifies that the IndexingService can correctly parse XML data and convert it into + * SolrInputDocument objects using the schema-less approach. + */ +@SpringBootTest +@TestPropertySource(locations = "classpath:application.properties") +class XmlIndexingTest { + + @Autowired + private IndexingDocumentCreator indexingDocumentCreator; + + @Test + void testCreateSchemalessDocumentsFromXmlSingleDocument() throws Exception { + // Given + + String xmlData = + """ + + A Game of Thrones + + George R.R. Martin + george@example.com + + 7.99 + true + fantasy + + """; + + // When + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromXml(xmlData); + + // Then + assertThat(documents).hasSize(1); + + SolrInputDocument doc = documents.getFirst(); + assertThat(doc.getFieldValue("id_attr")).isEqualTo("123"); + assertThat(doc.getFieldValue("book_title")).isEqualTo("A Game of Thrones"); + assertThat(doc.getFieldValue("book_author_name")).isEqualTo("George R.R. Martin"); + assertThat(doc.getFieldValue("book_author_email")).isEqualTo("george@example.com"); + assertThat(doc.getFieldValue("book_price")).isEqualTo("7.99"); + assertThat(doc.getFieldValue("book_instock")).isEqualTo("true"); + assertThat(doc.getFieldValue("book_genre")).isEqualTo("fantasy"); + } + + @Test + void testCreateSchemalessDocumentsFromXmlMultipleDocuments() throws Exception { + // Given + + String xmlData = + """ + + + A Game of Thrones + George R.R. Martin + fantasy + + + Foundation + Isaac Asimov + scifi + + + Dune + Frank Herbert + scifi + + + """; + + // When + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromXml(xmlData); + + // Then + assertThat(documents).hasSize(3); + + // Verify first document + SolrInputDocument firstDoc = documents.getFirst(); + assertThat(firstDoc.getFieldValue("id_attr")).isEqualTo("1"); + assertThat(firstDoc.getFieldValue("document_title")).isEqualTo("A Game of Thrones"); + assertThat(firstDoc.getFieldValue("document_author")).isEqualTo("George R.R. Martin"); + assertThat(firstDoc.getFieldValue("document_genre")).isEqualTo("fantasy"); + + // Verify second document + SolrInputDocument secondDoc = documents.get(1); + assertThat(secondDoc.getFieldValue("id_attr")).isEqualTo("2"); + assertThat(secondDoc.getFieldValue("document_title")).isEqualTo("Foundation"); + assertThat(secondDoc.getFieldValue("document_author")).isEqualTo("Isaac Asimov"); + assertThat(secondDoc.getFieldValue("document_genre")).isEqualTo("scifi"); + + // Verify third document + SolrInputDocument thirdDoc = documents.get(2); + assertThat(thirdDoc.getFieldValue("id_attr")).isEqualTo("3"); + assertThat(thirdDoc.getFieldValue("document_title")).isEqualTo("Dune"); + assertThat(thirdDoc.getFieldValue("document_author")).isEqualTo("Frank Herbert"); + assertThat(thirdDoc.getFieldValue("document_genre")).isEqualTo("scifi"); + } + + @Test + void testCreateSchemalessDocumentsFromXmlWithAttributes() throws Exception { + // Given + + String xmlData = + """ + + Smartphone + 599.99 + Latest smartphone with advanced features + + """; + + // When + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromXml(xmlData); + + // Then + assertThat(documents).hasSize(1); + + SolrInputDocument doc = documents.getFirst(); + assertThat(doc.getFieldValue("id_attr")).isEqualTo("P123"); + assertThat(doc.getFieldValue("category_attr")).isEqualTo("electronics"); + assertThat(doc.getFieldValue("featured_attr")).isEqualTo("true"); + assertThat(doc.getFieldValue("product_name_lang_attr")).isEqualTo("en"); + assertThat(doc.getFieldValue("product_price_currency_attr")).isEqualTo("USD"); + assertThat(doc.getFieldValue("product_name")).isEqualTo("Smartphone"); + assertThat(doc.getFieldValue("product_price")).isEqualTo("599.99"); + assertThat(doc.getFieldValue("product_description")) + .isEqualTo("Latest smartphone with advanced features"); + } + + @Test + void testCreateSchemalessDocumentsFromXmlWithEmptyValues() throws Exception { + // Given + + String xmlData = + """ + + + Product One + + 19.99 + + + + Product with no name + 29.99 + + + """; + + // When + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromXml(xmlData); + + // Then + assertThat(documents).hasSize(2); + + // First document should skip empty description + SolrInputDocument firstDoc = documents.getFirst(); + assertThat(firstDoc.getFieldValue("id_attr")).isEqualTo("1"); + assertThat(firstDoc.getFieldValue("item_name")).isEqualTo("Product One"); + assertThat(firstDoc.getFieldValue("item_description")) + .isNull(); // Empty element should not be indexed + assertThat(firstDoc.getFieldValue("item_price")).isEqualTo("19.99"); + + // Second document should skip empty name + SolrInputDocument secondDoc = documents.get(1); + assertThat(secondDoc.getFieldValue("id_attr")).isEqualTo("2"); + assertThat(secondDoc.getFieldValue("item_name")) + .isNull(); // Empty element should not be indexed + assertThat(secondDoc.getFieldValue("item_description")).isEqualTo("Product with no name"); + assertThat(secondDoc.getFieldValue("item_price")).isEqualTo("29.99"); + } + + @Test + void testCreateSchemalessDocumentsFromXmlWithRepeatedElements() throws Exception { + // Given + + String xmlData = + """ + + Programming Book + John Doe + + programming + java + software + + + Technology + Education + + + """; + + // When + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromXml(xmlData); + + // Then + assertThat(documents).hasSize(1); + + SolrInputDocument doc = documents.getFirst(); + assertThat(doc.getFieldValue("book_title")).isEqualTo("Programming Book"); + assertThat(doc.getFieldValue("book_author")).isEqualTo("John Doe"); + + // Check that repeated elements are handled properly + // Note: The current implementation processes each element separately, + // so we check for the individual tag and category fields + assertThat(doc.getFieldValue("book_tags_tag")).isNotNull(); + assertThat(doc.getFieldValue("book_categories_category")).isNotNull(); + } + + @Test + void testCreateSchemalessDocumentsFromXmlMixedContent() throws Exception { + // Given + + String xmlData = + """ +

+ Mixed Content Example + + This is some text content with + emphasized text + and more content here. + + Jane Smith +
+ """; + + // When + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromXml(xmlData); + + // Then + assertThat(documents).hasSize(1); + + SolrInputDocument doc = documents.getFirst(); + assertThat(doc.getFieldValue("article_title")).isEqualTo("Mixed Content Example"); + assertThat(doc.getFieldValue("article_author")).isEqualTo("Jane Smith"); + + // Mixed content should be handled - text content should be captured + assertThat(doc.getFieldValue("article_content")).isNotNull(); + assertThat(doc.getFieldValue("article_content_emphasis")).isEqualTo("emphasized text"); + } + + @Test + void testCreateSchemalessDocumentsFromXmlWithMalformedXml() { + // Given + + String malformedXml = + """ + + Incomplete Book + <author>John Doe</author> + </book> + """; + + // When/Then + assertThatThrownBy( + () -> + indexingDocumentCreator.createSchemalessDocumentsFromXml( + malformedXml)) + .isInstanceOf(RuntimeException.class); + } + + @Test + void testCreateSchemalessDocumentsFromXmlWithInvalidCharacters() { + // Given + + String invalidXml = + """ + <book> + <title>Book with invalid character: \u0000 + John Doe + + """; + + // When/Then + assertThatThrownBy( + () -> indexingDocumentCreator.createSchemalessDocumentsFromXml(invalidXml)) + .isInstanceOf(RuntimeException.class); + } + + @Test + void testCreateSchemalessDocumentsFromXmlWithDoctype() { + // Given + + String xmlWithDoctype = + """ + + + + + ]> + + Test Book + Test Author + + """; + + // When/Then - Should fail due to XXE protection + assertThatThrownBy( + () -> + indexingDocumentCreator.createSchemalessDocumentsFromXml( + xmlWithDoctype)) + .isInstanceOf(RuntimeException.class); + } + + @Test + void testCreateSchemalessDocumentsFromXmlWithExternalEntity() { + // Given + + String xmlWithExternalEntity = + """ + + + ]> + + &external; + Test Author + + """; + + // When/Then - Should fail due to XXE protection + assertThatThrownBy( + () -> + indexingDocumentCreator.createSchemalessDocumentsFromXml( + xmlWithExternalEntity)) + .isInstanceOf(RuntimeException.class); + } + + @Test + void testCreateSchemalessDocumentsFromXmlWithNullInput() { + // Given + + // When/Then + assertThatThrownBy(() -> indexingDocumentCreator.createSchemalessDocumentsFromXml(null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("XML input cannot be null or empty"); + } + + @Test + void testCreateSchemalessDocumentsFromXmlWithEmptyInput() { + // Given + + // When/Then + assertThatThrownBy(() -> indexingDocumentCreator.createSchemalessDocumentsFromXml("")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("XML input cannot be null or empty"); + } + + @Test + void testCreateSchemalessDocumentsFromXmlWithWhitespaceOnlyInput() { + // Given + + // When/Then + assertThatThrownBy( + () -> indexingDocumentCreator.createSchemalessDocumentsFromXml(" \n\t ")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("XML input cannot be null or empty"); + } + + @Test + void testCreateSchemalessDocumentsFromXmlWithLargeDocument() { + // Given + + // Create a large XML document (over 10MB) + StringBuilder largeXml = new StringBuilder(); + largeXml.append(""); + + // Add enough data to exceed the 10MB limit + String bookTemplate = + """ + + %s + %s + + """; + + // Create approximately 11MB of XML data + String longContent = "A".repeat(10000); // 10KB per book + for (int i = 0; i < 1200; i++) { // 1200 * 10KB = 12MB + largeXml.append(String.format(bookTemplate, i, "Title " + i, longContent)); + } + largeXml.append(""); + + // When/Then + String xmlString = largeXml.toString(); + assertThatThrownBy( + () -> indexingDocumentCreator.createSchemalessDocumentsFromXml(xmlString)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("XML document too large"); + } + + @Test + void testCreateSchemalessDocumentsFromXmlWithComplexNestedStructure() throws Exception { + // Given + + String complexXml = + """ + +
+ Smartphone + Teléfono inteligente + + Full HD+ + Primary camera + Front camera + + 128GB + Yes + + +
+ 599.99 + + + US + EU + APAC + + true + +
+ """; + + // When + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromXml(complexXml); + + // Then + assertThat(documents).hasSize(1); + + SolrInputDocument doc = documents.getFirst(); + + // Verify basic attributes + assertThat(doc.getFieldValue("id_attr")).isEqualTo("123"); + assertThat(doc.getFieldValue("category_attr")).isEqualTo("electronics"); + + // Verify nested structure flattening + assertThat(doc.getFieldValue("product_details_name_lang_attr")).isNotNull(); + assertThat(doc.getFieldValue("product_details_specifications_screen_size_attr")) + .isEqualTo("6.1"); + assertThat(doc.getFieldValue("product_details_specifications_screen_type_attr")) + .isEqualTo("OLED"); + assertThat(doc.getFieldValue("product_details_specifications_screen")) + .isEqualTo("Full HD+"); + + // Verify multiple similar elements + assertThat(doc.getFieldValue("product_details_specifications_camera_type_attr")) + .isNotNull(); + assertThat(doc.getFieldValue("product_details_specifications_camera_resolution_attr")) + .isNotNull(); + + // Verify deeply nested elements + assertThat(doc.getFieldValue("product_details_specifications_storage_internal")) + .isEqualTo("128GB"); + assertThat(doc.getFieldValue("product_details_specifications_storage_expandable")) + .isEqualTo("Yes"); + + // Verify pricing and availability + assertThat(doc.getFieldValue("product_pricing_currency_attr")).isEqualTo("USD"); + assertThat(doc.getFieldValue("product_pricing")).isEqualTo("599.99"); + assertThat(doc.getFieldValue("product_availability_instock")).isEqualTo("true"); + assertThat(doc.getFieldValue("product_availability_regions_region")).isNotNull(); + } + + @Test + void testFieldNameSanitization() throws Exception { + // Given + + String xmlWithSpecialChars = + """ + + Test Product + 99.99 + electronics + value + dashed value + uppercase value + + """; + + // When + List documents = + indexingDocumentCreator.createSchemalessDocumentsFromXml(xmlWithSpecialChars); + + // Then + assertThat(documents).hasSize(1); + + SolrInputDocument doc = documents.getFirst(); + + // Verify field name sanitization + assertThat(doc.getFieldValue("id_attr")).isEqualTo("123"); + assertThat(doc.getFieldValue("product_data_product_name")).isEqualTo("Test Product"); + assertThat(doc.getFieldValue("product_data_price_usd")).isEqualTo("99.99"); + assertThat(doc.getFieldValue("product_data_category_type")).isEqualTo("electronics"); + assertThat(doc.getFieldValue("product_data_field_with_multiple_underscores")) + .isEqualTo("value"); + assertThat(doc.getFieldValue("product_data_field_with_dashes")).isEqualTo("dashed value"); + assertThat(doc.getFieldValue("product_data_uppercase_field")).isEqualTo("uppercase value"); + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/metadata/CollectionServiceIntegrationTest.java b/src/test/java/org/apache/solr/mcp/server/metadata/CollectionServiceIntegrationTest.java new file mode 100644 index 0000000..9b87e54 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/metadata/CollectionServiceIntegrationTest.java @@ -0,0 +1,264 @@ +package org.apache.solr.mcp.server.metadata; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.request.CollectionAdminRequest; +import org.apache.solr.mcp.server.TestcontainersConfiguration; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +@Import(TestcontainersConfiguration.class) +class CollectionServiceIntegrationTest { + + private static final String TEST_COLLECTION = "test_collection"; + private static boolean initialized = false; + @Autowired + private CollectionService collectionService; + @Autowired + private SolrClient solrClient; + + @BeforeEach + void setupCollection() throws Exception { + + if (!initialized) { + // Create a test collection using the container's connection details + // Create a collection for testing + CollectionAdminRequest.Create createRequest = + CollectionAdminRequest.createCollection(TEST_COLLECTION, "_default", 1, 1); + createRequest.process(solrClient); + + // Verify collection was created successfully + CollectionAdminRequest.List listRequest = new CollectionAdminRequest.List(); + listRequest.process(solrClient); + + System.out.println("[DEBUG_LOG] Test collection created: " + TEST_COLLECTION); + initialized = true; + } + } + + @Test + void testListCollections() { + // Test listing collections + List collections = collectionService.listCollections(); + + // Print the collections for debugging + System.out.println("[DEBUG_LOG] Collections: " + collections); + + // Enhanced assertions for collections list + assertNotNull(collections, "Collections list should not be null"); + assertFalse(collections.isEmpty(), "Collections list should not be empty"); + + // Check if the test collection exists (either as exact name or as shard) + boolean testCollectionExists = + collections.contains(TEST_COLLECTION) + || collections.stream() + .anyMatch(col -> col.startsWith(TEST_COLLECTION + "_shard")); + assertTrue( + testCollectionExists, + "Collections should contain the test collection: " + + TEST_COLLECTION + + " (found: " + + collections + + ")"); + + // Verify collection names are not null or empty + for (String collection : collections) { + assertNotNull(collection, "Collection name should not be null"); + assertFalse(collection.trim().isEmpty(), "Collection name should not be empty"); + } + + // Verify expected collection characteristics + assertEquals( + collections.size(), + collections.stream().distinct().count(), + "Collection names should be unique"); + + // Verify that collections follow expected naming patterns + for (String collection : collections) { + // Collection names should either be simple names or shard names + assertTrue( + collection.matches("^[a-zA-Z0-9_]+(_shard\\d+_replica_n\\d+)?$"), + "Collection name should follow expected pattern: " + collection); + } + } + + @Test + void testGetCollectionStats() throws Exception { + // Test getting collection stats + SolrMetrics metrics = collectionService.getCollectionStats(TEST_COLLECTION); + + // Enhanced assertions for metrics + assertNotNull(metrics, "Collection stats should not be null"); + assertNotNull(metrics.timestamp(), "Timestamp should not be null"); + + // Verify index stats + assertNotNull(metrics.indexStats(), "Index stats should not be null"); + IndexStats indexStats = metrics.indexStats(); + assertNotNull(indexStats.numDocs(), "Number of documents should not be null"); + assertTrue(indexStats.numDocs() >= 0, "Number of documents should be non-negative"); + + // Verify query stats + assertNotNull(metrics.queryStats(), "Query stats should not be null"); + QueryStats queryStats = metrics.queryStats(); + assertNotNull(queryStats.queryTime(), "Query time should not be null"); + assertTrue(queryStats.queryTime() >= 0, "Query time should be non-negative"); + assertNotNull(queryStats.totalResults(), "Total results should not be null"); + assertTrue(queryStats.totalResults() >= 0, "Total results should be non-negative"); + assertNotNull(queryStats.start(), "Start should not be null"); + assertTrue(queryStats.start() >= 0, "Start should be non-negative"); + + // Verify timestamp is recent (within last 10 seconds) + long currentTime = System.currentTimeMillis(); + long timestampTime = metrics.timestamp().getTime(); + assertTrue( + currentTime - timestampTime < 10000, + "Timestamp should be recent (within 10 seconds)"); + + // Verify optional stats (cache and handler stats may be null, which is acceptable) + if (metrics.cacheStats() != null) { + CacheStats cacheStats = metrics.cacheStats(); + // Verify at least one cache type exists if cache stats are present + assertTrue( + cacheStats.queryResultCache() != null + || cacheStats.documentCache() != null + || cacheStats.filterCache() != null, + "At least one cache type should be present if cache stats exist"); + } + + if (metrics.handlerStats() != null) { + HandlerStats handlerStats = metrics.handlerStats(); + // Verify at least one handler type exists if handler stats are present + assertTrue( + handlerStats.selectHandler() != null || handlerStats.updateHandler() != null, + "At least one handler type should be present if handler stats exist"); + } + } + + @Test + void testCheckHealthHealthy() { + // Test checking health of a valid collection + SolrHealthStatus status = collectionService.checkHealth(TEST_COLLECTION); + + // Print the status for debugging + System.out.println("[DEBUG_LOG] Health status for valid collection: " + status); + + // Enhanced assertions for healthy collection + assertNotNull(status, "Health status should not be null"); + assertTrue(status.isHealthy(), "Collection should be healthy"); + + // Verify response time + assertNotNull(status.responseTime(), "Response time should not be null"); + assertTrue(status.responseTime() >= 0, "Response time should be non-negative"); + assertTrue( + status.responseTime() < 30000, "Response time should be reasonable (< 30 seconds)"); + + // Verify document count + assertNotNull(status.totalDocuments(), "Total documents should not be null"); + assertTrue(status.totalDocuments() >= 0, "Total documents should be non-negative"); + + // Verify timestamp + assertNotNull(status.lastChecked(), "Last checked timestamp should not be null"); + long currentTime = System.currentTimeMillis(); + long lastCheckedTime = status.lastChecked().getTime(); + assertTrue( + currentTime - lastCheckedTime < 5000, + "Last checked timestamp should be very recent (within 5 seconds)"); + + // Verify no error message for healthy collection + assertNull(status.errorMessage(), "Error message should be null for healthy collection"); + + // Verify string representation contains meaningful information + String statusString = status.toString(); + if (statusString != null) { + assertTrue( + statusString.contains("healthy") || statusString.contains("true"), + "Status string should indicate healthy state"); + } + } + + @Test + void testCheckHealthUnhealthy() { + // Test checking health of an invalid collection + String nonExistentCollection = "non_existent_collection"; + SolrHealthStatus status = collectionService.checkHealth(nonExistentCollection); + + // Print the status for debugging + System.out.println("[DEBUG_LOG] Health status for invalid collection: " + status); + + // Enhanced assertions for unhealthy collection + assertNotNull(status, "Health status should not be null"); + assertFalse(status.isHealthy(), "Collection should not be healthy"); + + // Verify timestamp + assertNotNull(status.lastChecked(), "Last checked timestamp should not be null"); + long currentTime = System.currentTimeMillis(); + long lastCheckedTime = status.lastChecked().getTime(); + assertTrue( + currentTime - lastCheckedTime < 5000, + "Last checked timestamp should be very recent (within 5 seconds)"); + + // Verify error message + assertNotNull( + status.errorMessage(), "Error message should not be null for unhealthy collection"); + assertFalse( + status.errorMessage().trim().isEmpty(), + "Error message should not be empty for unhealthy collection"); + + // Verify that performance metrics are null for unhealthy collection + assertNull(status.responseTime(), "Response time should be null for unhealthy collection"); + assertNull( + status.totalDocuments(), "Total documents should be null for unhealthy collection"); + + // Verify error message contains meaningful information + String errorMessage = status.errorMessage().toLowerCase(); + assertTrue( + errorMessage.contains("collection") + || errorMessage.contains("not found") + || errorMessage.contains("error") + || errorMessage.contains("fail"), + "Error message should contain meaningful error information"); + + // Verify string representation indicates unhealthy state + String statusString = status.toString(); + if (statusString != null) { + assertTrue( + statusString.contains("false") + || statusString.contains("unhealthy") + || statusString.contains("error"), + "Status string should indicate unhealthy state"); + } + } + + @Test + void testCollectionNameExtraction() { + // Test collection name extraction functionality + assertEquals( + TEST_COLLECTION, + collectionService.extractCollectionName(TEST_COLLECTION), + "Regular collection name should be returned as-is"); + + assertEquals( + "films", + collectionService.extractCollectionName("films_shard1_replica_n1"), + "Shard name should be extracted to base collection name"); + + assertEquals( + "products", + collectionService.extractCollectionName("products_shard2_replica_n3"), + "Complex shard name should be extracted correctly"); + + assertNull(collectionService.extractCollectionName(null), "Null input should return null"); + + assertEquals( + "", + collectionService.extractCollectionName(""), + "Empty string should return empty string"); + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/metadata/CollectionServiceTest.java b/src/test/java/org/apache/solr/mcp/server/metadata/CollectionServiceTest.java new file mode 100644 index 0000000..68eabd2 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/metadata/CollectionServiceTest.java @@ -0,0 +1,902 @@ +package org.apache.solr.mcp.server.metadata; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrRequest; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.impl.CloudSolrClient; +import org.apache.solr.client.solrj.response.LukeResponse; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.client.solrj.response.SolrPingResponse; +import org.apache.solr.common.SolrDocumentList; +import org.apache.solr.common.util.NamedList; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class CollectionServiceTest { + + @Mock + private SolrClient solrClient; + + @Mock + private CloudSolrClient cloudSolrClient; + + @Mock + private QueryResponse queryResponse; + + @Mock + private LukeResponse lukeResponse; + + @Mock + private SolrPingResponse pingResponse; + + private CollectionService collectionService; + + @BeforeEach + void setUp() { + collectionService = new CollectionService(solrClient); + } + + // Constructor tests + @Test + void constructor_ShouldInitializeWithSolrClient() { + assertNotNull(collectionService); + } + + @Test + void listCollections_WithCloudSolrClient_ShouldReturnCollections() { + // Given - This test verifies the service can be constructed with CloudSolrClient + CollectionService cloudService = new CollectionService(cloudSolrClient); + + // Note: This test cannot fully exercise listCollections() because it requires + // mocking static methods in CollectionAdminRequest which requires PowerMock or + // Mockito inline. The actual behavior is tested in integration tests. + + // When/Then - Verify service construction + assertNotNull(cloudService, "Should be able to construct service with CloudSolrClient"); + } + + @Test + void listCollections_WhenExceptionOccurs_ShouldReturnEmptyList() { + // Note: This test cannot fully exercise listCollections() with mock SolrClient + // because it requires mocking CoreAdminRequest processing. The actual error + // handling behavior is tested in integration tests. + + // Given/When - Using regular SolrClient (non-cloud) which will attempt CoreAdmin + // The mock doesn't have a real CoreAdmin implementation + + // Then - Verify service is constructed + assertNotNull(collectionService, "Service should be constructed successfully"); + } + + // Collection name extraction tests + @Test + void extractCollectionName_WithShardName_ShouldExtractCollectionName() { + // Given + String shardName = "films_shard1_replica_n1"; + + // When + String result = collectionService.extractCollectionName(shardName); + + // Then + assertEquals("films", result); + } + + @Test + void extractCollectionName_WithMultipleShards_ShouldExtractCorrectly() { + // Given & When & Then + assertEquals( + "products", collectionService.extractCollectionName("products_shard2_replica_n3")); + assertEquals("users", collectionService.extractCollectionName("users_shard5_replica_n10")); + } + + @Test + void extractCollectionName_WithSimpleCollectionName_ShouldReturnUnchanged() { + // Given + String simpleName = "simple_collection"; + + // When + String result = collectionService.extractCollectionName(simpleName); + + // Then + assertEquals("simple_collection", result); + } + + @Test + void extractCollectionName_WithNullInput_ShouldReturnNull() { + // When + String result = collectionService.extractCollectionName(null); + + // Then + assertNull(result); + } + + @Test + void extractCollectionName_WithEmptyString_ShouldReturnEmptyString() { + // When + String result = collectionService.extractCollectionName(""); + + // Then + assertEquals("", result); + } + + @Test + void + extractCollectionName_WithCollectionNameContainingUnderscore_ShouldOnlyExtractBeforeShard() { + // Given - collection name itself contains underscore + String complexName = "my_complex_collection_shard1_replica_n1"; + + // When + String result = collectionService.extractCollectionName(complexName); + + // Then + assertEquals("my_complex_collection", result); + } + + @Test + void extractCollectionName_EdgeCases_ShouldHandleCorrectly() { + // Test various edge cases + assertEquals("a", collectionService.extractCollectionName("a_shard1")); + assertEquals("collection", collectionService.extractCollectionName("collection_shard")); + assertEquals("test_name", collectionService.extractCollectionName("test_name")); + assertEquals("", collectionService.extractCollectionName("_shard1")); + } + + @Test + void extractCollectionName_WithShardInMiddleOfName_ShouldExtractCorrectly() { + // Given - "shard" appears in collection name but not as suffix pattern + String name = "resharding_tasks"; + + // When + String result = collectionService.extractCollectionName(name); + + // Then + assertEquals( + "resharding_tasks", + result, + "Should not extract when '_shard' is not followed by number"); + } + + @Test + void extractCollectionName_WithMultipleOccurrencesOfShard_ShouldUseFirst() { + // Given + String name = "data_shard1_shard2_replica_n1"; + + // When + String result = collectionService.extractCollectionName(name); + + // Then + assertEquals("data", result, "Should use first occurrence of '_shard'"); + } + + // Health check tests + @Test + void checkHealth_WithHealthyCollection_ShouldReturnHealthyStatus() throws Exception { + // Given + SolrDocumentList docList = new SolrDocumentList(); + docList.setNumFound(100); + + when(solrClient.ping("test_collection")).thenReturn(pingResponse); + when(pingResponse.getElapsedTime()).thenReturn(10L); + when(solrClient.query(eq("test_collection"), any())).thenReturn(queryResponse); + when(queryResponse.getResults()).thenReturn(docList); + + // When + SolrHealthStatus result = collectionService.checkHealth("test_collection"); + + // Then + assertNotNull(result); + assertTrue(result.isHealthy()); + assertNull(result.errorMessage()); + assertEquals(10L, result.responseTime()); + assertEquals(100L, result.totalDocuments()); + } + + @Test + void checkHealth_WithUnhealthyCollection_ShouldReturnUnhealthyStatus() throws Exception { + // Given + when(solrClient.ping("unhealthy_collection")) + .thenThrow(new SolrServerException("Connection failed")); + + // When + SolrHealthStatus result = collectionService.checkHealth("unhealthy_collection"); + + // Then + assertNotNull(result); + assertFalse(result.isHealthy()); + assertNotNull(result.errorMessage()); + assertTrue(result.errorMessage().contains("Connection failed")); + assertNull(result.responseTime()); + assertNull(result.totalDocuments()); + } + + @Test + void checkHealth_WhenPingSucceedsButQueryFails_ShouldReturnUnhealthyStatus() throws Exception { + // Given + when(solrClient.ping("test_collection")).thenReturn(pingResponse); + when(solrClient.query(eq("test_collection"), any())) + .thenThrow(new IOException("Query failed")); + + // When + SolrHealthStatus result = collectionService.checkHealth("test_collection"); + + // Then + assertNotNull(result); + assertFalse(result.isHealthy()); + assertNotNull(result.errorMessage()); + assertTrue(result.errorMessage().contains("Query failed")); + } + + @Test + void checkHealth_WithEmptyCollection_ShouldReturnHealthyWithZeroDocuments() throws Exception { + // Given + SolrDocumentList emptyDocList = new SolrDocumentList(); + emptyDocList.setNumFound(0); + + when(solrClient.ping("empty_collection")).thenReturn(pingResponse); + when(pingResponse.getElapsedTime()).thenReturn(5L); + when(solrClient.query(eq("empty_collection"), any())).thenReturn(queryResponse); + when(queryResponse.getResults()).thenReturn(emptyDocList); + + // When + SolrHealthStatus result = collectionService.checkHealth("empty_collection"); + + // Then + assertNotNull(result); + assertTrue(result.isHealthy()); + assertEquals(0L, result.totalDocuments()); + assertEquals(5, result.responseTime()); + } + + @Test + void checkHealth_WithSlowResponse_ShouldCaptureResponseTime() throws Exception { + // Given + SolrDocumentList docList = new SolrDocumentList(); + docList.setNumFound(1000); + + when(solrClient.ping("slow_collection")).thenReturn(pingResponse); + when(pingResponse.getElapsedTime()).thenReturn(5000L); // 5 seconds + when(solrClient.query(eq("slow_collection"), any())).thenReturn(queryResponse); + when(queryResponse.getResults()).thenReturn(docList); + + // When + SolrHealthStatus result = collectionService.checkHealth("slow_collection"); + + // Then + assertNotNull(result); + assertTrue(result.isHealthy()); + assertEquals(5000, result.responseTime()); + assertTrue(result.responseTime() > 1000, "Should capture slow response time"); + } + + @Test + void checkHealth_IOException() throws Exception { + when(solrClient.ping("error_collection")).thenThrow(new IOException("Network error")); + + SolrHealthStatus result = collectionService.checkHealth("error_collection"); + + assertFalse(result.isHealthy()); + assertTrue(result.errorMessage().contains("Network error")); + assertNull(result.responseTime()); + } + + // Query stats tests + @Test + void buildQueryStats_WithValidResponse_ShouldExtractStats() { + // Given + SolrDocumentList docList = new SolrDocumentList(); + docList.setNumFound(250); + docList.setStart(0); + docList.setMaxScore(1.5f); + + when(queryResponse.getQTime()).thenReturn(25); + when(queryResponse.getResults()).thenReturn(docList); + + // When + QueryStats result = collectionService.buildQueryStats(queryResponse); + + // Then + assertNotNull(result); + assertEquals(25, result.queryTime()); + assertEquals(250, result.totalResults()); + assertEquals(0, result.start()); + assertEquals(1.5f, result.maxScore()); + } + + @Test + void buildQueryStats_WithNullMaxScore_ShouldHandleGracefully() { + // Given + SolrDocumentList docList = new SolrDocumentList(); + docList.setNumFound(100); + docList.setStart(10); + docList.setMaxScore(null); + + when(queryResponse.getQTime()).thenReturn(15); + when(queryResponse.getResults()).thenReturn(docList); + + // When + QueryStats result = collectionService.buildQueryStats(queryResponse); + + // Then + assertNotNull(result); + assertEquals(15, result.queryTime()); + assertEquals(100, result.totalResults()); + assertEquals(10, result.start()); + assertNull(result.maxScore()); + } + + // Index stats tests + @Test + void buildIndexStats_ShouldExtractStats() { + NamedList indexInfo = new NamedList<>(); + indexInfo.add("segmentCount", 5); + when(lukeResponse.getIndexInfo()).thenReturn(indexInfo); + when(lukeResponse.getNumDocs()).thenReturn(1000); + + IndexStats result = collectionService.buildIndexStats(lukeResponse); + + assertEquals(1000, result.numDocs()); + assertEquals(5, result.segmentCount()); + } + + @Test + void buildIndexStats_WithNullSegmentCount() { + NamedList indexInfo = new NamedList<>(); + when(lukeResponse.getIndexInfo()).thenReturn(indexInfo); + when(lukeResponse.getNumDocs()).thenReturn(1000); + + IndexStats result = collectionService.buildIndexStats(lukeResponse); + + assertEquals(1000, result.numDocs()); + assertNull(result.segmentCount()); + } + + // Collection validation tests + @Test + void getCollectionStats_NotFound() { + CollectionService spyService = spy(collectionService); + doReturn(Collections.emptyList()).when(spyService).listCollections(); + + IllegalArgumentException exception = + assertThrows( + IllegalArgumentException.class, + () -> spyService.getCollectionStats("non_existent")); + + assertTrue(exception.getMessage().contains("Collection not found: non_existent")); + } + + @Test + void validateCollectionExists() throws Exception { + CollectionService spyService = spy(collectionService); + List collections = Arrays.asList("collection1", "films_shard1_replica_n1"); + doReturn(collections).when(spyService).listCollections(); + + Method method = + CollectionService.class.getDeclaredMethod("validateCollectionExists", String.class); + method.setAccessible(true); + + assertTrue((boolean) method.invoke(spyService, "collection1")); + assertTrue((boolean) method.invoke(spyService, "films")); + assertFalse((boolean) method.invoke(spyService, "non_existent")); + } + + @Test + void validateCollectionExists_WithException() throws Exception { + CollectionService spyService = spy(collectionService); + doReturn(Collections.emptyList()).when(spyService).listCollections(); + + Method method = + CollectionService.class.getDeclaredMethod("validateCollectionExists", String.class); + method.setAccessible(true); + + assertFalse((boolean) method.invoke(spyService, "any_collection")); + } + + // Cache metrics tests + @Test + void getCacheMetrics_WithNonExistentCollection_ShouldReturnNull() { + // When - Mock will not have collection configured + CacheStats result = collectionService.getCacheMetrics("nonexistent"); + + // Then + assertNull(result); + } + + @Test + void getCacheMetrics_Success() throws Exception { + CollectionService spyService = spy(collectionService); + doReturn(Arrays.asList("test_collection")).when(spyService).listCollections(); + + NamedList mbeans = createMockCacheData(); + when(solrClient.request(any(SolrRequest.class))).thenReturn(mbeans); + + CacheStats result = spyService.getCacheMetrics("test_collection"); + + assertNotNull(result); + assertNotNull(result.queryResultCache()); + assertEquals(100L, result.queryResultCache().lookups()); + } + + @Test + void getCacheMetrics_CollectionNotFound() { + CollectionService spyService = spy(collectionService); + doReturn(Collections.emptyList()).when(spyService).listCollections(); + + CacheStats result = spyService.getCacheMetrics("non_existent"); + + assertNull(result); + } + + @Test + void getCacheMetrics_SolrServerException() throws Exception { + CollectionService spyService = spy(collectionService); + doReturn(Arrays.asList("test_collection")).when(spyService).listCollections(); + + when(solrClient.request(any(SolrRequest.class))) + .thenThrow(new SolrServerException("Error")); + + CacheStats result = spyService.getCacheMetrics("test_collection"); + + assertNull(result); + } + + @Test + void getCacheMetrics_IOException() throws Exception { + CollectionService spyService = spy(collectionService); + doReturn(Arrays.asList("test_collection")).when(spyService).listCollections(); + + when(solrClient.request(any(SolrRequest.class))).thenThrow(new IOException("IO Error")); + + CacheStats result = spyService.getCacheMetrics("test_collection"); + + assertNull(result); + } + + @Test + void getCacheMetrics_EmptyStats() throws Exception { + CollectionService spyService = spy(collectionService); + doReturn(Arrays.asList("test_collection")).when(spyService).listCollections(); + + NamedList mbeans = new NamedList<>(); + mbeans.add("CACHE", new NamedList<>()); + when(solrClient.request(any(SolrRequest.class))).thenReturn(mbeans); + + CacheStats result = spyService.getCacheMetrics("test_collection"); + + assertNull(result); + } + + @Test + void getCacheMetrics_WithShardName() throws Exception { + CollectionService spyService = spy(collectionService); + doReturn(Arrays.asList("films_shard1_replica_n1")).when(spyService).listCollections(); + + NamedList mbeans = createMockCacheData(); + when(solrClient.request(any(SolrRequest.class))).thenReturn(mbeans); + + CacheStats result = spyService.getCacheMetrics("films_shard1_replica_n1"); + + assertNotNull(result); + } + + @Test + void extractCacheStats() throws Exception { + NamedList mbeans = createMockCacheData(); + Method method = + CollectionService.class.getDeclaredMethod("extractCacheStats", NamedList.class); + method.setAccessible(true); + + CacheStats result = (CacheStats) method.invoke(collectionService, mbeans); + + assertNotNull(result.queryResultCache()); + assertEquals(100L, result.queryResultCache().lookups()); + assertEquals(80L, result.queryResultCache().hits()); + } + + @Test + void extractCacheStats_AllCacheTypes() throws Exception { + NamedList mbeans = createCompleteMockCacheData(); + Method method = + CollectionService.class.getDeclaredMethod("extractCacheStats", NamedList.class); + method.setAccessible(true); + + CacheStats result = (CacheStats) method.invoke(collectionService, mbeans); + + assertNotNull(result.queryResultCache()); + assertNotNull(result.documentCache()); + assertNotNull(result.filterCache()); + } + + @Test + void extractCacheStats_NullCacheCategory() throws Exception { + NamedList mbeans = new NamedList<>(); + mbeans.add("CACHE", null); + + Method method = + CollectionService.class.getDeclaredMethod("extractCacheStats", NamedList.class); + method.setAccessible(true); + + CacheStats result = (CacheStats) method.invoke(collectionService, mbeans); + + assertNotNull(result); + assertNull(result.queryResultCache()); + assertNull(result.documentCache()); + assertNull(result.filterCache()); + } + + @Test + void isCacheStatsEmpty() throws Exception { + Method method = + CollectionService.class.getDeclaredMethod("isCacheStatsEmpty", CacheStats.class); + method.setAccessible(true); + + CacheStats emptyStats = new CacheStats(null, null, null); + assertTrue((boolean) method.invoke(collectionService, emptyStats)); + assertTrue((boolean) method.invoke(collectionService, (CacheStats) null)); + + CacheStats nonEmptyStats = + new CacheStats(new CacheInfo(100L, null, null, null, null, null), null, null); + assertFalse((boolean) method.invoke(collectionService, nonEmptyStats)); + } + + // Handler metrics tests + @Test + void getHandlerMetrics_WithNonExistentCollection_ShouldReturnNull() { + // When - Mock will not have collection configured + HandlerStats result = collectionService.getHandlerMetrics("nonexistent"); + + // Then + assertNull(result); + } + + @Test + void getHandlerMetrics_Success() throws Exception { + CollectionService spyService = spy(collectionService); + doReturn(Arrays.asList("test_collection")).when(spyService).listCollections(); + + NamedList mbeans = createMockHandlerData(); + when(solrClient.request(any(SolrRequest.class))).thenReturn(mbeans); + + HandlerStats result = spyService.getHandlerMetrics("test_collection"); + + assertNotNull(result); + assertNotNull(result.selectHandler()); + } + + @Test + void getHandlerMetrics_CollectionNotFound() { + CollectionService spyService = spy(collectionService); + doReturn(Collections.emptyList()).when(spyService).listCollections(); + + HandlerStats result = spyService.getHandlerMetrics("non_existent"); + + assertNull(result); + } + + @Test + void getHandlerMetrics_SolrServerException() throws Exception { + CollectionService spyService = spy(collectionService); + doReturn(Arrays.asList("test_collection")).when(spyService).listCollections(); + + when(solrClient.request(any(SolrRequest.class))) + .thenThrow(new SolrServerException("Error")); + + HandlerStats result = spyService.getHandlerMetrics("test_collection"); + + assertNull(result); + } + + @Test + void getHandlerMetrics_IOException() throws Exception { + CollectionService spyService = spy(collectionService); + doReturn(Arrays.asList("test_collection")).when(spyService).listCollections(); + + when(solrClient.request(any(SolrRequest.class))).thenThrow(new IOException("IO Error")); + + HandlerStats result = spyService.getHandlerMetrics("test_collection"); + + assertNull(result); + } + + @Test + void getHandlerMetrics_EmptyStats() throws Exception { + CollectionService spyService = spy(collectionService); + doReturn(Arrays.asList("test_collection")).when(spyService).listCollections(); + + NamedList mbeans = new NamedList<>(); + mbeans.add("QUERYHANDLER", new NamedList<>()); + when(solrClient.request(any(SolrRequest.class))).thenReturn(mbeans); + + HandlerStats result = spyService.getHandlerMetrics("test_collection"); + + assertNull(result); + } + + @Test + void getHandlerMetrics_WithShardName() throws Exception { + CollectionService spyService = spy(collectionService); + doReturn(Arrays.asList("films_shard1_replica_n1")).when(spyService).listCollections(); + + NamedList mbeans = createMockHandlerData(); + when(solrClient.request(any(SolrRequest.class))).thenReturn(mbeans); + + HandlerStats result = spyService.getHandlerMetrics("films_shard1_replica_n1"); + + assertNotNull(result); + } + + @Test + void extractHandlerStats() throws Exception { + NamedList mbeans = createMockHandlerData(); + Method method = + CollectionService.class.getDeclaredMethod("extractHandlerStats", NamedList.class); + method.setAccessible(true); + + HandlerStats result = (HandlerStats) method.invoke(collectionService, mbeans); + + assertNotNull(result.selectHandler()); + assertEquals(500L, result.selectHandler().requests()); + } + + @Test + void extractHandlerStats_BothHandlers() throws Exception { + NamedList mbeans = createCompleteHandlerData(); + Method method = + CollectionService.class.getDeclaredMethod("extractHandlerStats", NamedList.class); + method.setAccessible(true); + + HandlerStats result = (HandlerStats) method.invoke(collectionService, mbeans); + + assertNotNull(result.selectHandler()); + assertNotNull(result.updateHandler()); + assertEquals(500L, result.selectHandler().requests()); + assertEquals(250L, result.updateHandler().requests()); + } + + @Test + void extractHandlerStats_NullHandlerCategory() throws Exception { + NamedList mbeans = new NamedList<>(); + mbeans.add("QUERYHANDLER", null); + + Method method = + CollectionService.class.getDeclaredMethod("extractHandlerStats", NamedList.class); + method.setAccessible(true); + + HandlerStats result = (HandlerStats) method.invoke(collectionService, mbeans); + + assertNotNull(result); + assertNull(result.selectHandler()); + assertNull(result.updateHandler()); + } + + @Test + void isHandlerStatsEmpty() throws Exception { + Method method = + CollectionService.class.getDeclaredMethod( + "isHandlerStatsEmpty", HandlerStats.class); + method.setAccessible(true); + + HandlerStats emptyStats = new HandlerStats(null, null); + assertTrue((boolean) method.invoke(collectionService, emptyStats)); + assertTrue((boolean) method.invoke(collectionService, (HandlerStats) null)); + + HandlerStats nonEmptyStats = + new HandlerStats(new HandlerInfo(100L, null, null, null, null, null), null); + assertFalse((boolean) method.invoke(collectionService, nonEmptyStats)); + } + + // List collections tests + @Test + void listCollections_CloudClient_Success() throws Exception { + CloudSolrClient cloudClient = mock(CloudSolrClient.class); + + NamedList response = new NamedList<>(); + response.add("collections", Arrays.asList("collection1", "collection2")); + + when(cloudClient.request(any(), any())).thenReturn(response); + + CollectionService service = new CollectionService(cloudClient); + List result = service.listCollections(); + + assertNotNull(result); + assertEquals(2, result.size()); + assertTrue(result.contains("collection1")); + assertTrue(result.contains("collection2")); + } + + @Test + void listCollections_CloudClient_NullCollections() throws Exception { + CloudSolrClient cloudClient = mock(CloudSolrClient.class); + + NamedList response = new NamedList<>(); + response.add("collections", null); + + when(cloudClient.request(any(), any())).thenReturn(response); + + CollectionService service = new CollectionService(cloudClient); + List result = service.listCollections(); + + assertNotNull(result); + assertTrue(result.isEmpty()); + } + + @Test + void listCollections_CloudClient_Error() throws Exception { + CloudSolrClient cloudClient = mock(CloudSolrClient.class); + when(cloudClient.request(any(), any())) + .thenThrow(new SolrServerException("Connection error")); + + CollectionService service = new CollectionService(cloudClient); + List result = service.listCollections(); + + assertNotNull(result); + assertTrue(result.isEmpty()); + } + + @Test + void listCollections_NonCloudClient_Success() throws Exception { + // Create a NamedList to represent the core status response + NamedList response = new NamedList<>(); + NamedList status = new NamedList<>(); + + NamedList core1Status = new NamedList<>(); + NamedList core2Status = new NamedList<>(); + + status.add("core1", core1Status); + status.add("core2", core2Status); + response.add("status", status); + + // Mock the solrClient request to return the response + when(solrClient.request(any(), any())).thenReturn(response); + + CollectionService service = new CollectionService(solrClient); + List result = service.listCollections(); + + assertNotNull(result); + assertEquals(2, result.size()); + assertTrue(result.contains("core1")); + assertTrue(result.contains("core2")); + } + + @Test + void listCollections_NonCloudClient_Error() throws Exception { + when(solrClient.request(any(), any())).thenThrow(new IOException("IO error")); + + CollectionService service = new CollectionService(solrClient); + List result = service.listCollections(); + + assertNotNull(result); + assertTrue(result.isEmpty()); + } + + // Helper methods + private NamedList createMockCacheData() { + NamedList mbeans = new NamedList<>(); + NamedList cacheCategory = new NamedList<>(); + NamedList queryResultCache = new NamedList<>(); + NamedList queryStats = new NamedList<>(); + + queryStats.add("lookups", 100L); + queryStats.add("hits", 80L); + queryStats.add("hitratio", 0.8f); + queryStats.add("inserts", 20L); + queryStats.add("evictions", 5L); + queryStats.add("size", 100L); + queryResultCache.add("stats", queryStats); + cacheCategory.add("queryResultCache", queryResultCache); + mbeans.add("CACHE", cacheCategory); + + return mbeans; + } + + private NamedList createCompleteMockCacheData() { + NamedList mbeans = new NamedList<>(); + NamedList cacheCategory = new NamedList<>(); + + // Query Result Cache + NamedList queryResultCache = new NamedList<>(); + NamedList queryStats = new NamedList<>(); + queryStats.add("lookups", 100L); + queryStats.add("hits", 80L); + queryStats.add("hitratio", 0.8f); + queryStats.add("inserts", 20L); + queryStats.add("evictions", 5L); + queryStats.add("size", 100L); + queryResultCache.add("stats", queryStats); + + // Document Cache + NamedList documentCache = new NamedList<>(); + NamedList docStats = new NamedList<>(); + docStats.add("lookups", 200L); + docStats.add("hits", 150L); + docStats.add("hitratio", 0.75f); + docStats.add("inserts", 50L); + docStats.add("evictions", 10L); + docStats.add("size", 180L); + documentCache.add("stats", docStats); + + // Filter Cache + NamedList filterCache = new NamedList<>(); + NamedList filterStats = new NamedList<>(); + filterStats.add("lookups", 150L); + filterStats.add("hits", 120L); + filterStats.add("hitratio", 0.8f); + filterStats.add("inserts", 30L); + filterStats.add("evictions", 8L); + filterStats.add("size", 140L); + filterCache.add("stats", filterStats); + + cacheCategory.add("queryResultCache", queryResultCache); + cacheCategory.add("documentCache", documentCache); + cacheCategory.add("filterCache", filterCache); + mbeans.add("CACHE", cacheCategory); + + return mbeans; + } + + private NamedList createMockHandlerData() { + NamedList mbeans = new NamedList<>(); + NamedList queryHandlerCategory = new NamedList<>(); + NamedList selectHandler = new NamedList<>(); + NamedList selectStats = new NamedList<>(); + + selectStats.add("requests", 500L); + selectStats.add("errors", 5L); + selectStats.add("timeouts", 2L); + selectStats.add("totalTime", 10000L); + selectStats.add("avgTimePerRequest", 20.0f); + selectStats.add("avgRequestsPerSecond", 25.0f); + selectHandler.add("stats", selectStats); + queryHandlerCategory.add("/select", selectHandler); + mbeans.add("QUERYHANDLER", queryHandlerCategory); + + return mbeans; + } + + private NamedList createCompleteHandlerData() { + NamedList mbeans = new NamedList<>(); + NamedList queryHandlerCategory = new NamedList<>(); + + // Select Handler + NamedList selectHandler = new NamedList<>(); + NamedList selectStats = new NamedList<>(); + selectStats.add("requests", 500L); + selectStats.add("errors", 5L); + selectStats.add("timeouts", 2L); + selectStats.add("totalTime", 10000L); + selectStats.add("avgTimePerRequest", 20.0f); + selectStats.add("avgRequestsPerSecond", 25.0f); + selectHandler.add("stats", selectStats); + + // Update Handler + NamedList updateHandler = new NamedList<>(); + NamedList updateStats = new NamedList<>(); + updateStats.add("requests", 250L); + updateStats.add("errors", 2L); + updateStats.add("timeouts", 1L); + updateStats.add("totalTime", 5000L); + updateStats.add("avgTimePerRequest", 20.0f); + updateStats.add("avgRequestsPerSecond", 50.0f); + updateHandler.add("stats", updateStats); + + queryHandlerCategory.add("/select", selectHandler); + queryHandlerCategory.add("/update", updateHandler); + mbeans.add("QUERYHANDLER", queryHandlerCategory); + + return mbeans; + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/metadata/CollectionUtilsTest.java b/src/test/java/org/apache/solr/mcp/server/metadata/CollectionUtilsTest.java new file mode 100644 index 0000000..c5b5809 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/metadata/CollectionUtilsTest.java @@ -0,0 +1,296 @@ +package org.apache.solr.mcp.server.metadata; + +import org.apache.solr.common.util.NamedList; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +/** + * Comprehensive test suite for the Utils utility class. Tests all public methods and edge cases for + * type-safe value extraction from Solr NamedList objects. + */ +class CollectionUtilsTest { + + @Test + void testGetLong_withNullValue() { + NamedList namedList = new NamedList<>(); + namedList.add("nullKey", null); + + assertNull(CollectionUtils.getLong(namedList, "nullKey")); + } + + @Test + void testGetLong_withMissingKey() { + NamedList namedList = new NamedList<>(); + + assertNull(CollectionUtils.getLong(namedList, "missingKey")); + } + + @Test + void testGetLong_withIntegerValue() { + NamedList namedList = new NamedList<>(); + namedList.add("intKey", 123); + + assertEquals(123L, CollectionUtils.getLong(namedList, "intKey")); + } + + @Test + void testGetLong_withLongValue() { + NamedList namedList = new NamedList<>(); + namedList.add("longKey", 123456789L); + + assertEquals(123456789L, CollectionUtils.getLong(namedList, "longKey")); + } + + @Test + void testGetLong_withDoubleValue() { + NamedList namedList = new NamedList<>(); + namedList.add("doubleKey", 123.45); + + assertEquals(123L, CollectionUtils.getLong(namedList, "doubleKey")); + } + + @Test + void testGetLong_withFloatValue() { + NamedList namedList = new NamedList<>(); + namedList.add("floatKey", 123.45f); + + assertEquals(123L, CollectionUtils.getLong(namedList, "floatKey")); + } + + @Test + void testGetLong_withBigIntegerValue() { + NamedList namedList = new NamedList<>(); + namedList.add("bigIntKey", new BigInteger("123456789")); + + assertEquals(123456789L, CollectionUtils.getLong(namedList, "bigIntKey")); + } + + @Test + void testGetLong_withBigDecimalValue() { + NamedList namedList = new NamedList<>(); + namedList.add("bigDecKey", new BigDecimal("123.45")); + + assertEquals(123L, CollectionUtils.getLong(namedList, "bigDecKey")); + } + + @Test + void testGetLong_withValidStringValue() { + NamedList namedList = new NamedList<>(); + namedList.add("stringKey", "123456"); + + assertEquals(123456L, CollectionUtils.getLong(namedList, "stringKey")); + } + + @Test + void testGetLong_withInvalidStringValue() { + NamedList namedList = new NamedList<>(); + namedList.add("invalidStringKey", "not_a_number"); + + assertNull(CollectionUtils.getLong(namedList, "invalidStringKey")); + } + + @Test + void testGetLong_withEmptyStringValue() { + NamedList namedList = new NamedList<>(); + namedList.add("emptyStringKey", ""); + + assertNull(CollectionUtils.getLong(namedList, "emptyStringKey")); + } + + @Test + void testGetFloat_withNullValue() { + NamedList namedList = new NamedList<>(); + namedList.add("nullKey", null); + + assertEquals(0.0f, CollectionUtils.getFloat(namedList, "nullKey")); + } + + @Test + void testGetFloat_withMissingKey() { + NamedList namedList = new NamedList<>(); + + assertEquals(0.0f, CollectionUtils.getFloat(namedList, "missingKey")); + } + + @Test + void testGetFloat_withIntegerValue() { + NamedList namedList = new NamedList<>(); + namedList.add("intKey", 123); + + assertEquals(123.0f, CollectionUtils.getFloat(namedList, "intKey")); + } + + @Test + void testGetFloat_withFloatValue() { + NamedList namedList = new NamedList<>(); + namedList.add("floatKey", 123.45f); + + assertEquals(123.45f, CollectionUtils.getFloat(namedList, "floatKey"), 0.001f); + } + + @Test + void testGetFloat_withDoubleValue() { + NamedList namedList = new NamedList<>(); + namedList.add("doubleKey", 123.456789); + + assertEquals(123.456789f, CollectionUtils.getFloat(namedList, "doubleKey"), 0.001f); + } + + @Test + void testGetFloat_withLongValue() { + NamedList namedList = new NamedList<>(); + namedList.add("longKey", 123456789L); + + assertEquals(123456789.0f, CollectionUtils.getFloat(namedList, "longKey")); + } + + @Test + void testGetFloat_withBigDecimalValue() { + NamedList namedList = new NamedList<>(); + namedList.add("bigDecKey", new BigDecimal("123.45")); + + assertEquals(123.45f, CollectionUtils.getFloat(namedList, "bigDecKey"), 0.001f); + } + + @Test + void testGetInteger_withNullValue() { + NamedList namedList = new NamedList<>(); + namedList.add("nullKey", null); + + assertNull(CollectionUtils.getInteger(namedList, "nullKey")); + } + + @Test + void testGetInteger_withMissingKey() { + NamedList namedList = new NamedList<>(); + + assertNull(CollectionUtils.getInteger(namedList, "missingKey")); + } + + @Test + void testGetInteger_withIntegerValue() { + NamedList namedList = new NamedList<>(); + namedList.add("intKey", 123); + + assertEquals(123, CollectionUtils.getInteger(namedList, "intKey")); + } + + @Test + void testGetInteger_withLongValue() { + NamedList namedList = new NamedList<>(); + namedList.add("longKey", 123456L); + + assertEquals(123456, CollectionUtils.getInteger(namedList, "longKey")); + } + + @Test + void testGetInteger_withDoubleValue() { + NamedList namedList = new NamedList<>(); + namedList.add("doubleKey", 123.45); + + assertEquals(123, CollectionUtils.getInteger(namedList, "doubleKey")); + } + + @Test + void testGetInteger_withFloatValue() { + NamedList namedList = new NamedList<>(); + namedList.add("floatKey", 123.45f); + + assertEquals(123, CollectionUtils.getInteger(namedList, "floatKey")); + } + + @Test + void testGetInteger_withBigIntegerValue() { + NamedList namedList = new NamedList<>(); + namedList.add("bigIntKey", new BigInteger("123456")); + + assertEquals(123456, CollectionUtils.getInteger(namedList, "bigIntKey")); + } + + @Test + void testGetInteger_withValidStringValue() { + NamedList namedList = new NamedList<>(); + namedList.add("stringKey", "123456"); + + assertEquals(123456, CollectionUtils.getInteger(namedList, "stringKey")); + } + + @Test + void testGetInteger_withInvalidStringValue() { + NamedList namedList = new NamedList<>(); + namedList.add("invalidStringKey", "not_a_number"); + + assertNull(CollectionUtils.getInteger(namedList, "invalidStringKey")); + } + + @Test + void testGetInteger_withEmptyStringValue() { + NamedList namedList = new NamedList<>(); + namedList.add("emptyStringKey", ""); + + assertNull(CollectionUtils.getInteger(namedList, "emptyStringKey")); + } + + @Test + void testGetInteger_withOverflowValue() { + NamedList namedList = new NamedList<>(); + // Value larger than Integer.MAX_VALUE + namedList.add("overflowKey", Long.MAX_VALUE); + + // Should truncate to int value (overflow behavior) + assertEquals(-1, CollectionUtils.getInteger(namedList, "overflowKey")); + } + + @Test + void testGetLong_withNegativeValues() { + NamedList namedList = new NamedList<>(); + namedList.add("negativeKey", -123456); + + assertEquals(-123456L, CollectionUtils.getLong(namedList, "negativeKey")); + } + + @Test + void testGetFloat_withNegativeValues() { + NamedList namedList = new NamedList<>(); + namedList.add("negativeKey", -123.45f); + + assertEquals(-123.45f, CollectionUtils.getFloat(namedList, "negativeKey"), 0.001f); + } + + @Test + void testGetInteger_withNegativeValues() { + NamedList namedList = new NamedList<>(); + namedList.add("negativeKey", -123456); + + assertEquals(-123456, CollectionUtils.getInteger(namedList, "negativeKey")); + } + + @Test + void testGetLong_withZeroValue() { + NamedList namedList = new NamedList<>(); + namedList.add("zeroKey", 0); + + assertEquals(0L, CollectionUtils.getLong(namedList, "zeroKey")); + } + + @Test + void testGetFloat_withZeroValue() { + NamedList namedList = new NamedList<>(); + namedList.add("zeroKey", 0.0f); + + assertEquals(0.0f, CollectionUtils.getFloat(namedList, "zeroKey")); + } + + @Test + void testGetInteger_withZeroValue() { + NamedList namedList = new NamedList<>(); + namedList.add("zeroKey", 0); + + assertEquals(0, CollectionUtils.getInteger(namedList, "zeroKey")); + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/metadata/SchemaServiceIntegrationTest.java b/src/test/java/org/apache/solr/mcp/server/metadata/SchemaServiceIntegrationTest.java new file mode 100644 index 0000000..5fdb3ae --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/metadata/SchemaServiceIntegrationTest.java @@ -0,0 +1,181 @@ +package org.apache.solr.mcp.server.metadata; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.request.CollectionAdminRequest; +import org.apache.solr.client.solrj.response.schema.SchemaRepresentation; +import org.apache.solr.mcp.server.TestcontainersConfiguration; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Integration test suite for SchemaService using real Solr containers. Tests actual schema + * retrieval functionality against a live Solr instance. + */ +@SpringBootTest +@Import(TestcontainersConfiguration.class) +class SchemaServiceIntegrationTest { + + private static final String TEST_COLLECTION = "schema_test_collection"; + private static boolean initialized = false; + @Autowired + private SchemaService schemaService; + @Autowired + private SolrClient solrClient; + + @BeforeEach + void setupCollection() throws Exception { + // Create a collection for testing + if (!initialized) { + CollectionAdminRequest.Create createRequest = + CollectionAdminRequest.createCollection(TEST_COLLECTION, "_default", 1, 1); + createRequest.process(solrClient); + initialized = true; + } + } + + @Test + void testGetSchema_ValidCollection() throws Exception { + // When + SchemaRepresentation schema = schemaService.getSchema(TEST_COLLECTION); + + // Then + assertNotNull(schema, "Schema should not be null"); + assertNotNull(schema.getFields(), "Schema fields should not be null"); + assertNotNull(schema.getFieldTypes(), "Schema field types should not be null"); + + // Verify basic schema properties + assertFalse(schema.getFields().isEmpty(), "Schema should have at least some fields"); + assertFalse( + schema.getFieldTypes().isEmpty(), "Schema should have at least some field types"); + + // Check for common default fields in Solr + boolean hasIdField = + schema.getFields().stream().anyMatch(field -> "id".equals(field.get("name"))); + assertTrue(hasIdField, "Schema should have an 'id' field"); + + // Check for common field types + boolean hasStringType = + schema.getFieldTypes().stream() + .anyMatch( + fieldType -> + "string".equals(fieldType.getAttributes().get("name"))); + assertTrue(hasStringType, "Schema should have a 'string' field type"); + } + + @Test + void testGetSchema_InvalidCollection() { + // When/Then + assertThrows( + Exception.class, + () -> { + schemaService.getSchema("non_existent_collection_12345"); + }, + "Getting schema for non-existent collection should throw exception"); + } + + @Test + void testGetSchema_NullCollection() { + // When/Then + assertThrows( + Exception.class, + () -> { + schemaService.getSchema(null); + }, + "Getting schema with null collection should throw exception"); + } + + @Test + void testGetSchema_EmptyCollection() { + // When/Then + assertThrows( + Exception.class, + () -> { + schemaService.getSchema(""); + }, + "Getting schema with empty collection should throw exception"); + } + + @Test + void testGetSchema_ValidatesSchemaContent() throws Exception { + // When + SchemaRepresentation schema = schemaService.getSchema(TEST_COLLECTION); + + // Then - verify schema has expected structure + assertNotNull(schema.getName(), "Schema should have a name"); + + // Check that we can access field details + schema.getFields() + .forEach( + field -> { + assertNotNull(field.get("name"), "Field should have a name"); + assertNotNull(field.get("type"), "Field should have a type"); + // indexed and stored can be null (defaults to true in many cases) + }); + + // Check that we can access field type details + schema.getFieldTypes() + .forEach( + fieldType -> { + assertNotNull( + fieldType.getAttributes().get("name"), + "Field type should have a name"); + assertNotNull( + fieldType.getAttributes().get("class"), + "Field type should have a class"); + }); + } + + @Test + void testGetSchema_ChecksDynamicFields() throws Exception { + // When + SchemaRepresentation schema = schemaService.getSchema(TEST_COLLECTION); + + // Then - verify dynamic fields are accessible + assertNotNull(schema.getDynamicFields(), "Dynamic fields should not be null"); + + // Most Solr schemas have some dynamic fields by default + assertTrue(schema.getDynamicFields().size() >= 0, "Dynamic fields should be a valid list"); + + // Check for common dynamic field patterns + boolean hasStringDynamicField = + schema.getDynamicFields().stream() + .anyMatch( + dynField -> { + String name = (String) dynField.get("name"); + return name != null + && (name.contains("*_s") || name.contains("*_str")); + }); + + assertTrue(hasStringDynamicField, "Schema should have string dynamic fields"); + } + + @Test + void testGetSchema_ChecksCopyFields() throws Exception { + // When + SchemaRepresentation schema = schemaService.getSchema(TEST_COLLECTION); + + // Then - verify copy fields are accessible + assertNotNull(schema.getCopyFields(), "Copy fields should not be null"); + + // Copy fields list can be empty, that's valid + assertTrue(schema.getCopyFields().size() >= 0, "Copy fields should be a valid list"); + } + + @Test + void testGetSchema_ReturnsUniqueKey() throws Exception { + // When + SchemaRepresentation schema = schemaService.getSchema(TEST_COLLECTION); + + // Then - verify unique key is accessible + // Unique key can be null in some schemas, but the method should work + // Most default schemas have 'id' as unique key + if (schema.getUniqueKey() != null) { + assertNotNull(schema.getUniqueKey(), "Unique key should be accessible"); + } + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/metadata/SchemaServiceTest.java b/src/test/java/org/apache/solr/mcp/server/metadata/SchemaServiceTest.java new file mode 100644 index 0000000..7801f31 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/metadata/SchemaServiceTest.java @@ -0,0 +1,142 @@ +package org.apache.solr.mcp.server.metadata; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.request.schema.SchemaRequest; +import org.apache.solr.client.solrj.response.schema.SchemaRepresentation; +import org.apache.solr.client.solrj.response.schema.SchemaResponse; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +/** + * Comprehensive test suite for the SchemaService class. Tests schema retrieval functionality with + * various scenarios including success and error cases. + */ +@ExtendWith(MockitoExtension.class) +class SchemaServiceTest { + + @Mock + private SolrClient solrClient; + + @Mock + private SchemaResponse schemaResponse; + + @Mock + private SchemaRepresentation schemaRepresentation; + + private SchemaService schemaService; + + @BeforeEach + void setUp() { + schemaService = new SchemaService(solrClient); + } + + @Test + void testSchemaService_InstantiatesCorrectly() { + // Given/When + SchemaService service = new SchemaService(solrClient); + + // Then + assertNotNull(service, "SchemaService should be instantiated correctly"); + } + + @Test + void testGetSchema_CollectionNotFound() throws Exception { + // Given + final String nonExistentCollection = "non_existent_collection"; + + // When SolrClient throws an exception for non-existent collection + when(solrClient.request(any(SchemaRequest.class), eq(nonExistentCollection))) + .thenThrow( + new SolrServerException("Collection not found: " + nonExistentCollection)); + + // Then + assertThrows( + Exception.class, + () -> { + schemaService.getSchema(nonExistentCollection); + }); + } + + @Test + void testGetSchema_SolrServerException() throws Exception { + // Given + final String collectionName = "test_collection"; + + // When SolrClient throws a SolrServerException + when(solrClient.request(any(SchemaRequest.class), eq(collectionName))) + .thenThrow(new SolrServerException("Solr server error")); + + // Then + assertThrows( + Exception.class, + () -> { + schemaService.getSchema(collectionName); + }); + } + + @Test + void testGetSchema_IOException() throws Exception { + // Given + final String collectionName = "test_collection"; + + // When SolrClient throws an IOException + when(solrClient.request(any(SchemaRequest.class), eq(collectionName))) + .thenThrow(new IOException("Network connection error")); + + // Then + assertThrows( + Exception.class, + () -> { + schemaService.getSchema(collectionName); + }); + } + + @Test + void testGetSchema_WithNullCollection() { + // Given a null collection name + // Then should throw an exception (NullPointerException or IllegalArgumentException) + assertThrows( + Exception.class, + () -> { + schemaService.getSchema(null); + }); + } + + @Test + void testGetSchema_WithEmptyCollection() { + // Given an empty collection name + // Then should throw an exception + assertThrows( + Exception.class, + () -> { + schemaService.getSchema(""); + }); + } + + @Test + void testConstructor() { + // Test that constructor properly initializes the service + SchemaService service = new SchemaService(solrClient); + assertNotNull(service); + } + + @Test + void testConstructor_WithNullClient() { + // Test constructor with null client + assertDoesNotThrow( + () -> { + new SchemaService(null); + }); + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/search/SearchServiceDirectTest.java b/src/test/java/org/apache/solr/mcp/server/search/SearchServiceDirectTest.java new file mode 100644 index 0000000..91b81b3 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/search/SearchServiceDirectTest.java @@ -0,0 +1,279 @@ +package org.apache.solr.mcp.server.search; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.response.FacetField; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.SolrDocumentList; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class SearchServiceDirectTest { + + @Mock + private SolrClient solrClient; + + @Mock + private QueryResponse queryResponse; + + private SearchService searchService; + + @BeforeEach + void setUp() { + searchService = new SearchService(solrClient); + } + + @Test + void testBasicSearch() throws SolrServerException, IOException { + // Setup mock response + SolrDocumentList documents = new SolrDocumentList(); + documents.setNumFound(2); + documents.setStart(0); + documents.setMaxScore(1.0f); + + SolrDocument doc1 = new SolrDocument(); + doc1.addField("id", "1"); + doc1.addField("name", List.of("Book 1")); + doc1.addField("author", List.of("Author 1")); + + SolrDocument doc2 = new SolrDocument(); + doc2.addField("id", "2"); + doc2.addField("name", List.of("Book 2")); + doc2.addField("author", List.of("Author 2")); + + documents.add(doc1); + documents.add(doc2); + + when(queryResponse.getResults()).thenReturn(documents); + when(solrClient.query(eq("books"), any(SolrQuery.class))).thenReturn(queryResponse); + + // Test + SearchResponse result = searchService.search("books", null, null, null, null, null, null); + + // Verify + assertNotNull(result); + assertEquals(2L, result.numFound()); + + List> resultDocs = result.documents(); + assertEquals(2, resultDocs.size()); + assertEquals("1", resultDocs.getFirst().get("id")); + assertEquals("2", resultDocs.get(1).get("id")); + } + + @Test + void testSearchWithFacets() throws SolrServerException, IOException { + // Setup mock response + SolrDocumentList documents = new SolrDocumentList(); + documents.setNumFound(2); + documents.setStart(0); + documents.setMaxScore(1.0f); + + SolrDocument doc1 = new SolrDocument(); + doc1.addField("id", "1"); + doc1.addField("genre_s", "fantasy"); + + SolrDocument doc2 = new SolrDocument(); + doc2.addField("id", "2"); + doc2.addField("genre_s", "scifi"); + + documents.add(doc1); + documents.add(doc2); + + // Create facet fields + List facetFields = new ArrayList<>(); + FacetField genreFacet = new FacetField("genre_s"); + genreFacet.add("fantasy", 1); + genreFacet.add("scifi", 1); + facetFields.add(genreFacet); + + when(queryResponse.getResults()).thenReturn(documents); + when(queryResponse.getFacetFields()).thenReturn(facetFields); + when(solrClient.query(eq("books"), any(SolrQuery.class))).thenReturn(queryResponse); + + // Test + SearchResponse result = searchService.search("books", null, null, null, null, null, null); + + // Verify + assertNotNull(result); + assertTrue(result.facets().containsKey("genre_s")); + + Map genreFacets = result.facets().get("genre_s"); + assertEquals(2, genreFacets.size()); + assertEquals(1L, genreFacets.get("fantasy")); + assertEquals(1L, genreFacets.get("scifi")); + } + + @Test + void testSearchWithEmptyResults() throws SolrServerException, IOException { + // Setup mock response with empty results + SolrDocumentList emptyDocuments = new SolrDocumentList(); + emptyDocuments.setNumFound(0); + emptyDocuments.setStart(0); + emptyDocuments.setMaxScore(0.0f); + + when(queryResponse.getResults()).thenReturn(emptyDocuments); + when(solrClient.query(eq("books"), any(SolrQuery.class))).thenReturn(queryResponse); + + // Test + SearchResponse result = + searchService.search("books", "nonexistent_query", null, null, null, null, null); + + // Verify + assertNotNull(result); + assertEquals(0L, result.numFound()); + assertEquals(0, result.documents().size()); + assertTrue(result.facets().isEmpty()); + } + + @Test + void testSearchWithEmptyFacets() throws SolrServerException, IOException { + // Setup mock response with documents but no facets + SolrDocumentList documents = new SolrDocumentList(); + documents.setNumFound(2); + documents.setStart(0); + documents.setMaxScore(1.0f); + + SolrDocument doc1 = new SolrDocument(); + doc1.addField("id", "1"); + doc1.addField("name", "Book 1"); + + SolrDocument doc2 = new SolrDocument(); + doc2.addField("id", "2"); + doc2.addField("name", "Book 2"); + + documents.add(doc1); + documents.add(doc2); + + when(queryResponse.getResults()).thenReturn(documents); + when(queryResponse.getFacetFields()).thenReturn(null); // No facet fields + when(solrClient.query(eq("books"), any(SolrQuery.class))).thenReturn(queryResponse); + + // Test with facet fields requested but none returned + SearchResponse result = + searchService.search("books", null, null, List.of("genre_s"), null, null, null); + + // Verify + assertNotNull(result); + assertEquals(2L, result.numFound()); + assertEquals(2, result.documents().size()); + assertTrue(result.facets().isEmpty()); + } + + @Test + void testSearchWithEmptyFacetValues() throws SolrServerException, IOException { + // Setup mock response with facet fields but no values + SolrDocumentList documents = new SolrDocumentList(); + documents.setNumFound(2); + documents.setStart(0); + documents.setMaxScore(1.0f); + + SolrDocument doc1 = new SolrDocument(); + doc1.addField("id", "1"); + SolrDocument doc2 = new SolrDocument(); + doc2.addField("id", "2"); + + documents.add(doc1); + documents.add(doc2); + + // Create facet field with no values + List facetFields = new ArrayList<>(); + FacetField emptyFacet = new FacetField("genre_s"); + facetFields.add(emptyFacet); + + when(queryResponse.getResults()).thenReturn(documents); + when(queryResponse.getFacetFields()).thenReturn(facetFields); + when(solrClient.query(eq("books"), any(SolrQuery.class))).thenReturn(queryResponse); + + // Test + SearchResponse result = + searchService.search("books", null, null, List.of("genre_s"), null, null, null); + + // Verify + assertNotNull(result); + assertEquals(2L, result.numFound()); + assertTrue(result.facets().containsKey("genre_s")); + assertTrue(result.facets().get("genre_s").isEmpty()); + } + + @Test + void testSearchWithSolrError() { + // Setup mock to throw exception + try { + when(solrClient.query(eq("books"), any(SolrQuery.class))) + .thenThrow(new SolrServerException("Simulated Solr server error")); + + // Test + assertThrows( + SolrServerException.class, + () -> { + searchService.search("books", null, null, null, null, null, null); + }); + } catch (Exception e) { + fail("Test setup failed: " + e.getMessage()); + } + } + + @Test + void testSearchWithAllParameters() throws SolrServerException, IOException { + // Setup mock response + SolrDocumentList documents = new SolrDocumentList(); + documents.setNumFound(1); + documents.setStart(5); + documents.setMaxScore(0.75f); + + SolrDocument doc = new SolrDocument(); + doc.addField("id", "5"); + doc.addField("name", "Book 5"); + doc.addField("author", "Author 5"); + doc.addField("genre_s", "mystery"); + doc.addField("price", 12.99); + + documents.add(doc); + + // Create facet fields + List facetFields = new ArrayList<>(); + FacetField genreFacet = new FacetField("genre_s"); + genreFacet.add("mystery", 1); + facetFields.add(genreFacet); + + when(queryResponse.getResults()).thenReturn(documents); + when(queryResponse.getFacetFields()).thenReturn(facetFields); + when(solrClient.query(eq("books"), any(SolrQuery.class))).thenReturn(queryResponse); + + // Test with all parameters + List filterQueries = List.of("price:[10 TO 15]"); + List facetFields2 = List.of("genre_s", "author"); + List> sortClauses = List.of(Map.of("item", "price", "order", "desc")); + + SearchResponse result = + searchService.search( + "books", "mystery", filterQueries, facetFields2, sortClauses, 5, 10); + + // Verify + assertNotNull(result); + assertEquals(1L, result.numFound()); + assertEquals(5, result.start()); + assertEquals(0.75f, result.maxScore()); + assertEquals(1, result.documents().size()); + assertEquals("5", result.documents().getFirst().get("id")); + assertEquals("Book 5", result.documents().getFirst().get("name")); + assertTrue(result.facets().containsKey("genre_s")); + assertEquals(1L, result.facets().get("genre_s").get("mystery")); + } +} diff --git a/src/test/java/org/apache/solr/mcp/server/search/SearchServiceTest.java b/src/test/java/org/apache/solr/mcp/server/search/SearchServiceTest.java new file mode 100644 index 0000000..6b1748f --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/search/SearchServiceTest.java @@ -0,0 +1,763 @@ +package org.apache.solr.mcp.server.search; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.request.CollectionAdminRequest; +import org.apache.solr.client.solrj.response.FacetField; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.SolrDocumentList; +import org.apache.solr.mcp.server.TestcontainersConfiguration; +import org.apache.solr.mcp.server.indexing.IndexingService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.OptionalDouble; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Combined tests for SearchService: integration + unit (mocked SolrClient) in one class. + */ +@SpringBootTest +@Import(TestcontainersConfiguration.class) +class SearchServiceTest { + + // ===== Integration test context ===== + private static final String COLLECTION_NAME = "search_test_" + System.currentTimeMillis(); + private static boolean initialized = false; + @Autowired + private SearchService searchService; + @Autowired + private IndexingService indexingService; + @Autowired + private SolrClient solrClient; + + @BeforeEach + void setUp() throws Exception { + if (!initialized) { + CollectionAdminRequest.Create createRequest = + CollectionAdminRequest.createCollection(COLLECTION_NAME, "_default", 1, 1); + createRequest.process(solrClient); + + String sampleData = + """ + [ + { + "id": "book001", + "name": ["A Game of Thrones"], + "author_ss": ["George R.R. Martin"], + "price": [7.99], + "genre_s": "fantasy", + "series_s": "A Song of Ice and Fire", + "sequence_i": 1, + "cat_ss": ["book"] + }, + { + "id": "book002", + "name": ["A Clash of Kings"], + "author_ss": ["George R.R. Martin"], + "price": [8.99], + "genre_s": "fantasy", + "series_s": "A Song of Ice and Fire", + "sequence_i": 2, + "cat_ss": ["book"] + }, + { + "id": "book003", + "name": ["A Storm of Swords"], + "author_ss": ["George R.R. Martin"], + "price": [9.99], + "genre_s": "fantasy", + "series_s": "A Song of Ice and Fire", + "sequence_i": 3, + "cat_ss": ["book"] + }, + { + "id": "book004", + "name": ["The Hobbit"], + "author_ss": ["J.R.R. Tolkien"], + "price": [6.99], + "genre_s": "fantasy", + "series_s": "Middle Earth", + "sequence_i": 1, + "cat_ss": ["book"] + }, + { + "id": "book005", + "name": ["Dune"], + "author_ss": ["Frank Herbert"], + "price": [10.99], + "genre_s": "scifi", + "series_s": "Dune", + "sequence_i": 1, + "cat_ss": ["book"] + }, + { + "id": "book006", + "name": ["Foundation"], + "author_ss": ["Isaac Asimov"], + "price": [5.99], + "genre_s": "scifi", + "series_s": "Foundation", + "sequence_i": 1, + "cat_ss": ["book"] + }, + { + "id": "book007", + "name": ["The Fellowship of the Ring"], + "author_ss": ["J.R.R. Tolkien"], + "price": [8.99], + "genre_s": "fantasy", + "series_s": "The Lord of the Rings", + "sequence_i": 1, + "cat_ss": ["book"] + }, + { + "id": "book008", + "name": ["The Two Towers"], + "author_ss": ["J.R.R. Tolkien"], + "price": [8.99], + "genre_s": "fantasy", + "series_s": "The Lord of the Rings", + "sequence_i": 2, + "cat_ss": ["book"] + }, + { + "id": "book009", + "name": ["The Return of the King"], + "author_ss": ["J.R.R. Tolkien"], + "price": [8.99], + "genre_s": "fantasy", + "series_s": "The Lord of the Rings", + "sequence_i": 3, + "cat_ss": ["book"] + }, + { + "id": "book010", + "name": ["Neuromancer"], + "author_ss": ["William Gibson"], + "price": [7.99], + "genre_s": "scifi", + "series_s": "Sprawl", + "sequence_i": 1, + "cat_ss": ["book"] + } + ] + """; + + indexingService.indexJsonDocuments(COLLECTION_NAME, sampleData); + solrClient.commit(COLLECTION_NAME); + initialized = true; + } + } + + // ===== Integration tests (from original SearchServiceTest) ===== + + @Test + void testBasicSearch() throws SolrServerException, IOException { + SearchResponse result = + searchService.search(COLLECTION_NAME, null, null, null, null, null, null); + assertNotNull(result); + List> documents = result.documents(); + assertFalse(documents.isEmpty()); + assertEquals(10, documents.size()); + } + + @Test + void testSearchWithQuery() throws SolrServerException, IOException { + SearchResponse result = + searchService.search( + COLLECTION_NAME, "name:\"Game of Thrones\"", null, null, null, null, null); + assertNotNull(result); + List> documents = result.documents(); + assertEquals(1, documents.size()); + Map book = documents.getFirst(); + assertEquals("A Game of Thrones", ((List) book.get("name")).getFirst()); + } + + @Test + void testSearchReturnsAuthor() throws Exception { + SearchResponse result = + searchService.search( + COLLECTION_NAME, + "author_ss:\"George R.R. Martin\"", + null, + null, + null, + null, + null); + assertNotNull(result); + List> documents = result.documents(); + assertEquals(3, documents.size()); + Map book = documents.getFirst(); + assertEquals("George R.R. Martin", ((List) book.get("author_ss")).getFirst()); + } + + @Test + void testSearchWithFacets() throws Exception { + SearchResponse result = + searchService.search( + COLLECTION_NAME, null, null, List.of("genre_s"), null, null, null); + assertNotNull(result); + Map> facets = result.facets(); + assertNotNull(facets); + assertTrue(facets.containsKey("genre_s")); + } + + @Test + void testSearchWithPrice() throws Exception { + SearchResponse result = + searchService.search(COLLECTION_NAME, null, null, null, null, null, null); + assertNotNull(result); + List> documents = result.documents(); + assertFalse(documents.isEmpty()); + Map book = documents.getFirst(); + double currentPrice = + ((List) book.get("price")).isEmpty() + ? 0.0 + : ((Number) ((List) book.get("price")).getFirst()).doubleValue(); + assertTrue(currentPrice > 0); + } + + @Test + void testSortByPriceAscending() throws Exception { + List> sortClauses = List.of(Map.of("item", "price", "order", "asc")); + SearchResponse result = + searchService.search(COLLECTION_NAME, null, null, null, sortClauses, null, null); + assertNotNull(result); + List> documents = result.documents(); + assertFalse(documents.isEmpty()); + double previousPrice = 0.0; + for (Map book : documents) { + OptionalDouble priceOpt = extractPrice(book); + if (priceOpt.isEmpty()) continue; + double currentPrice = priceOpt.getAsDouble(); + assertTrue( + currentPrice >= previousPrice, + "Books should be sorted by price in ascending order"); + previousPrice = currentPrice; + } + } + + @Test + void testSortByPriceDescending() throws Exception { + List> sortClauses = List.of(Map.of("item", "price", "order", "desc")); + SearchResponse result = + searchService.search(COLLECTION_NAME, null, null, null, sortClauses, null, null); + assertNotNull(result); + List> documents = result.documents(); + assertFalse(documents.isEmpty()); + double previousPrice = Double.MAX_VALUE; + for (Map book : documents) { + OptionalDouble priceOpt = extractPrice(book); + if (priceOpt.isEmpty()) continue; + double currentPrice = priceOpt.getAsDouble(); + assertTrue( + currentPrice <= previousPrice, + "Books should be sorted by price in descending order"); + previousPrice = currentPrice; + } + } + + @Test + void testSortBySequence() throws Exception { + List> sortClauses = + List.of(Map.of("item", "sequence_i", "order", "asc")); + List filterQueries = List.of("series_s:\"A Song of Ice and Fire\""); + SearchResponse result = + searchService.search( + COLLECTION_NAME, null, filterQueries, null, sortClauses, null, null); + assertNotNull(result); + List> documents = result.documents(); + assertFalse(documents.isEmpty()); + int previousSequence = 0; + for (Map book : documents) { + int currentSequence = ((Number) book.get("sequence_i")).intValue(); + assertTrue( + currentSequence >= previousSequence, + "Books should be sorted by sequence_i in ascending order"); + previousSequence = currentSequence; + } + } + + @Test + void testFilterByGenre() throws Exception { + List filterQueries = List.of("genre_s:fantasy"); + SearchResponse result = + searchService.search(COLLECTION_NAME, null, filterQueries, null, null, null, null); + assertNotNull(result); + List> documents = result.documents(); + assertFalse(documents.isEmpty()); + for (Map book : documents) { + String genre = (String) book.get("genre_s"); + assertEquals("fantasy", genre, "All books should have genre_s = fantasy"); + } + } + + @Test + void testFilterByPriceRange() throws Exception { + List filterQueries = List.of("price:[6.0 TO 7.0]"); + SearchResponse result = + searchService.search(COLLECTION_NAME, null, filterQueries, null, null, null, null); + assertNotNull(result); + List> documents = result.documents(); + assertFalse(documents.isEmpty()); + for (Map book : documents) { + if (book.get("price") == null) continue; + OptionalDouble priceOpt = extractPrice(book); + if (priceOpt.isEmpty()) continue; + double price = priceOpt.getAsDouble(); + assertTrue( + price >= 6.0 && price <= 7.0, + "All books should have price between 6.0 and 7.0"); + } + } + + @Test + void testCombinedSortingAndFiltering() throws Exception { + List> sortClauses = List.of(Map.of("item", "price", "order", "desc")); + List filterQueries = List.of("genre_s:fantasy"); + SearchResponse result = + searchService.search( + COLLECTION_NAME, null, filterQueries, null, sortClauses, null, null); + assertNotNull(result); + List> documents = result.documents(); + assertFalse(documents.isEmpty()); + for (Map book : documents) { + String genre = (String) book.get("genre_s"); + assertEquals("fantasy", genre, "All books should have genre_s = fantasy"); + } + double previousPrice = Double.MAX_VALUE; + for (Map book : documents) { + Object priceObj = book.get("price"); + double currentPrice; + if (priceObj instanceof List) { + List priceList = (List) priceObj; + if (priceList.isEmpty()) { + continue; + } + currentPrice = ((Number) priceList.getFirst()).doubleValue(); + } else if (priceObj instanceof Number) { + currentPrice = ((Number) priceObj).doubleValue(); + } else { + continue; + } + assertTrue( + currentPrice <= previousPrice, + "Books should be sorted by price in descending order"); + previousPrice = currentPrice; + } + } + + @Test + void testPagination() throws Exception { + SearchResponse allResults = + searchService.search(COLLECTION_NAME, null, null, null, null, null, null); + assertNotNull(allResults); + long totalDocuments = allResults.numFound(); + assertTrue(totalDocuments > 0, "Should have at least some documents"); + SearchResponse firstPage = + searchService.search(COLLECTION_NAME, null, null, null, null, 0, 2); + assertNotNull(firstPage); + assertEquals(0, firstPage.start(), "Start offset should be 0"); + assertEquals(totalDocuments, firstPage.numFound(), "Total count should match"); + assertEquals(2, firstPage.documents().size(), "Should return exactly 2 documents"); + SearchResponse secondPage = + searchService.search(COLLECTION_NAME, null, null, null, null, 2, 2); + assertNotNull(secondPage); + assertEquals(2, secondPage.start(), "Start offset should be 2"); + assertEquals(totalDocuments, secondPage.numFound(), "Total count should match"); + assertEquals(2, secondPage.documents().size(), "Should return exactly 2 documents"); + List firstPageIds = getDocumentIds(firstPage.documents()); + List secondPageIds = getDocumentIds(secondPage.documents()); + for (String id : firstPageIds) { + assertFalse( + secondPageIds.contains(id), + "Second page should not contain documents from first page"); + } + } + + @Test + void testSpecialCharactersInQuery() throws Exception { + String specialJson = + """ + [ + { + "id": "special001", + "title": "Book with special characters: & + - ! ( ) { } [ ] ^ \\" ~ * ? : \\\\ /", + "author_ss": ["Special Author (with parentheses)"], + "description": "This is a test document with special characters: & + - ! ( ) { } [ ] ^ \\" ~ * ? : \\\\ /" + } + ] + """; + indexingService.indexJsonDocuments(COLLECTION_NAME, specialJson); + solrClient.commit(COLLECTION_NAME); + String query = "id:special001"; + SearchResponse result = + searchService.search(COLLECTION_NAME, query, null, null, null, null, null); + assertNotNull(result); + assertEquals(1, result.numFound(), "Should find exactly one document"); + query = "author_ss:\"Special Author \\(" + "with parentheses\\)\""; // escape parentheses + result = searchService.search(COLLECTION_NAME, query, null, null, null, null, null); + assertNotNull(result); + assertEquals(1, result.numFound(), "Should find exactly one document"); + query = "title:special*"; + result = searchService.search(COLLECTION_NAME, query, null, null, null, null, null); + assertNotNull(result); + assertTrue(result.numFound() > 0, "Should find at least one document"); + } + + // ===== Unit-style tests with mocked SolrClient (from SearchServiceUnitTest) ===== + + @Test + void unit_constructor_ShouldInitializeWithSolrClient() { + SearchService localService = new SearchService(mock(SolrClient.class)); + assertNotNull(localService); + } + + @Test + void unit_search_WithNullQuery_ShouldDefaultToMatchAll() throws Exception { + SolrClient mockClient = mock(SolrClient.class); + QueryResponse mockResponse = mock(QueryResponse.class); + SolrDocumentList mockDocuments = createMockDocumentList(); + when(mockResponse.getResults()).thenReturn(mockDocuments); + when(mockResponse.getFacetFields()).thenReturn(null); + when(mockClient.query(eq("test_collection"), any(SolrQuery.class))) + .thenAnswer( + invocation -> { + SolrQuery q = invocation.getArgument(1); + assertEquals("*:*", q.getQuery()); + return mockResponse; + }); + SearchService localService = new SearchService(mockClient); + SearchResponse result = + localService.search("test_collection", null, null, null, null, null, null); + assertNotNull(result); + } + + @Test + void unit_search_WithCustomQuery_ShouldUseProvidedQuery() throws Exception { + SolrClient mockClient = mock(SolrClient.class); + QueryResponse mockResponse = mock(QueryResponse.class); + String customQuery = "name:\"Spring Boot\""; + SolrDocumentList mockDocuments = createMockDocumentList(); + when(mockResponse.getResults()).thenReturn(mockDocuments); + when(mockResponse.getFacetFields()).thenReturn(null); + when(mockClient.query(eq("test_collection"), any(SolrQuery.class))) + .thenAnswer( + invocation -> { + SolrQuery q = invocation.getArgument(1); + assertEquals(customQuery, q.getQuery()); + return mockResponse; + }); + SearchService localService = new SearchService(mockClient); + SearchResponse result = + localService.search("test_collection", customQuery, null, null, null, null, null); + assertNotNull(result); + } + + @Test + void unit_search_WithFilterQueries_ShouldApplyFilters() throws Exception { + SolrClient mockClient = mock(SolrClient.class); + QueryResponse mockResponse = mock(QueryResponse.class); + List filterQueries = List.of("genre_s:fantasy", "price:[0 TO 10]"); + SolrDocumentList mockDocuments = createMockDocumentList(); + when(mockResponse.getResults()).thenReturn(mockDocuments); + when(mockResponse.getFacetFields()).thenReturn(null); + when(mockClient.query(eq("test_collection"), any(SolrQuery.class))) + .thenAnswer( + invocation -> { + SolrQuery q = invocation.getArgument(1); + assertArrayEquals(filterQueries.toArray(), q.getFilterQueries()); + return mockResponse; + }); + SearchService localService = new SearchService(mockClient); + SearchResponse result = + localService.search("test_collection", null, filterQueries, null, null, null, null); + assertNotNull(result); + } + + @Test + void unit_search_WithFacetFields_ShouldEnableFaceting() throws Exception { + SolrClient mockClient = mock(SolrClient.class); + QueryResponse mockResponse = mock(QueryResponse.class); + List facetFields = List.of("genre_s", "author_ss"); + SolrDocumentList mockDocuments = createMockDocumentList(); + when(mockResponse.getResults()).thenReturn(mockDocuments); + when(mockResponse.getFacetFields()).thenReturn(createMockFacetFields()); + when(mockClient.query(eq("test_collection"), any(SolrQuery.class))) + .thenAnswer(invocation -> mockResponse); + SearchService localService = new SearchService(mockClient); + SearchResponse result = + localService.search("test_collection", null, null, facetFields, null, null, null); + assertNotNull(result); + assertNotNull(result.facets()); + } + + @Test + void unit_search_WithSortClauses_ShouldApplySorting() throws Exception { + SolrClient mockClient = mock(SolrClient.class); + QueryResponse mockResponse = mock(QueryResponse.class); + List> sortClauses = + List.of( + Map.of("item", "price", "order", "asc"), + Map.of("item", "name", "order", "desc")); + SolrDocumentList mockDocuments = createMockDocumentList(); + when(mockResponse.getResults()).thenReturn(mockDocuments); + when(mockResponse.getFacetFields()).thenReturn(null); + when(mockClient.query(eq("test_collection"), any(SolrQuery.class))) + .thenAnswer(invocation -> mockResponse); + SearchService localService = new SearchService(mockClient); + SearchResponse result = + localService.search("test_collection", null, null, null, sortClauses, null, null); + assertNotNull(result); + } + + @Test + void unit_search_WithPagination_ShouldApplyStartAndRows() throws Exception { + SolrClient mockClient = mock(SolrClient.class); + QueryResponse mockResponse = mock(QueryResponse.class); + Integer start = 10; + Integer rows = 20; + SolrDocumentList mockDocuments = createMockDocumentList(); + when(mockResponse.getResults()).thenReturn(mockDocuments); + when(mockResponse.getFacetFields()).thenReturn(null); + when(mockClient.query(eq("test_collection"), any(SolrQuery.class))) + .thenAnswer( + invocation -> { + SolrQuery q = invocation.getArgument(1); + assertEquals(start, q.getStart()); + assertEquals(rows, q.getRows()); + return mockResponse; + }); + SearchService localService = new SearchService(mockClient); + SearchResponse result = + localService.search("test_collection", null, null, null, null, start, rows); + assertNotNull(result); + } + + @Test + void unit_search_WithAllParameters_ShouldCombineAllOptions() throws Exception { + SolrClient mockClient = mock(SolrClient.class); + QueryResponse mockResponse = mock(QueryResponse.class); + String query = "title:Java"; + List filterQueries = List.of("inStock:true"); + List facetFields = List.of("category"); + List> sortClauses = List.of(Map.of("item", "price", "order", "asc")); + Integer start = 0; + Integer rows = 10; + SolrDocumentList mockDocuments = createMockDocumentList(); + when(mockResponse.getResults()).thenReturn(mockDocuments); + when(mockResponse.getFacetFields()).thenReturn(createMockFacetFields()); + when(mockClient.query(eq("test_collection"), any(SolrQuery.class))) + .thenAnswer( + invocation -> { + SolrQuery captured = invocation.getArgument(1); + assertEquals(query, captured.getQuery()); + assertArrayEquals(filterQueries.toArray(), captured.getFilterQueries()); + assertNotNull(captured.getFacetFields()); + assertEquals(start, captured.getStart()); + assertEquals(rows, captured.getRows()); + return mockResponse; + }); + SearchService localService = new SearchService(mockClient); + SearchResponse result = + localService.search( + "test_collection", + query, + filterQueries, + facetFields, + sortClauses, + start, + rows); + assertNotNull(result); + } + + @Test + void unit_search_WhenSolrThrowsException_ShouldPropagateException() throws Exception { + SolrClient mockClient = mock(SolrClient.class); + when(mockClient.query(eq("test_collection"), any(SolrQuery.class))) + .thenThrow(new SolrServerException("Connection error")); + SearchService localService = new SearchService(mockClient); + assertThrows( + SolrServerException.class, + () -> localService.search("test_collection", null, null, null, null, null, null)); + } + + @Test + void unit_search_WhenIOException_ShouldPropagateException() throws Exception { + SolrClient mockClient = mock(SolrClient.class); + when(mockClient.query(eq("test_collection"), any(SolrQuery.class))) + .thenThrow(new IOException("Network error")); + SearchService localService = new SearchService(mockClient); + assertThrows( + IOException.class, + () -> localService.search("test_collection", null, null, null, null, null, null)); + } + + @Test + void unit_search_WithEmptyResults_ShouldReturnEmptyDocumentList() throws Exception { + SolrClient mockClient = mock(SolrClient.class); + QueryResponse mockResponse = mock(QueryResponse.class); + SolrDocumentList emptyDocuments = new SolrDocumentList(); + emptyDocuments.setNumFound(0); + emptyDocuments.setStart(0); + when(mockResponse.getResults()).thenReturn(emptyDocuments); + when(mockResponse.getFacetFields()).thenReturn(null); + when(mockClient.query(eq("test_collection"), any(SolrQuery.class))) + .thenReturn(mockResponse); + SearchService localService = new SearchService(mockClient); + SearchResponse result = + localService.search( + "test_collection", "nonexistent:value", null, null, null, null, null); + assertNotNull(result); + assertEquals(0, result.numFound()); + assertTrue(result.documents().isEmpty()); + } + + @Test + void unit_search_WithNullFilterQueries_ShouldNotApplyFilters() throws Exception { + SolrClient mockClient = mock(SolrClient.class); + QueryResponse mockResponse = mock(QueryResponse.class); + SolrDocumentList mockDocuments = createMockDocumentList(); + when(mockResponse.getResults()).thenReturn(mockDocuments); + when(mockResponse.getFacetFields()).thenReturn(null); + when(mockClient.query(eq("test_collection"), any(SolrQuery.class))) + .thenAnswer( + invocation -> { + SolrQuery q = invocation.getArgument(1); + assertNull(q.getFilterQueries()); + return mockResponse; + }); + SearchService localService = new SearchService(mockClient); + SearchResponse result = + localService.search("test_collection", null, null, null, null, null, null); + assertNotNull(result); + } + + @Test + void unit_search_WithEmptyFacetFields_ShouldNotEnableFaceting() throws Exception { + SolrClient mockClient = mock(SolrClient.class); + QueryResponse mockResponse = mock(QueryResponse.class); + SolrDocumentList mockDocuments = createMockDocumentList(); + when(mockResponse.getResults()).thenReturn(mockDocuments); + when(mockResponse.getFacetFields()).thenReturn(null); + when(mockClient.query(eq("test_collection"), any(SolrQuery.class))) + .thenAnswer( + invocation -> { + SolrQuery q = invocation.getArgument(1); + assertNull(q.getFacetFields()); + return mockResponse; + }); + SearchService localService = new SearchService(mockClient); + SearchResponse result = + localService.search("test_collection", null, null, List.of(), null, null, null); + assertNotNull(result); + } + + @Test + void unit_searchResponse_ShouldContainAllFields() throws Exception { + SolrClient mockClient = mock(SolrClient.class); + QueryResponse mockResponse = mock(QueryResponse.class); + SolrDocumentList mockDocuments = createMockDocumentListWithData(); + when(mockResponse.getResults()).thenReturn(mockDocuments); + when(mockResponse.getFacetFields()).thenReturn(createMockFacetFields()); + when(mockClient.query(eq("test_collection"), any(SolrQuery.class))) + .thenReturn(mockResponse); + SearchService localService = new SearchService(mockClient); + SearchResponse result = + localService.search( + "test_collection", null, null, List.of("genre_s"), null, null, null); + assertNotNull(result); + assertEquals(2, result.numFound()); + assertEquals(0, result.start()); + assertNotNull(result.documents()); + assertEquals(2, result.documents().size()); + assertNotNull(result.facets()); + assertFalse(result.facets().isEmpty()); + } + + // ===== Helpers (from unit tests and integration tests) ===== + + private OptionalDouble extractPrice(Map document) { + Object priceObj = document.get("price"); + if (priceObj == null) { + return OptionalDouble.empty(); + } + if (priceObj instanceof List) { + List priceList = (List) priceObj; + if (priceList.isEmpty()) { + return OptionalDouble.empty(); + } + return OptionalDouble.of(((Number) priceList.getFirst()).doubleValue()); + } else if (priceObj instanceof Number) { + return OptionalDouble.of(((Number) priceObj).doubleValue()); + } + return OptionalDouble.empty(); + } + + private List getDocumentIds(List> documents) { + List ids = new ArrayList<>(); + for (Map doc : documents) { + Object idObj = doc.get("id"); + if (idObj instanceof List) { + ids.add(((List) idObj).getFirst().toString()); + } else if (idObj != null) { + ids.add(idObj.toString()); + } + } + return ids; + } + + private SolrDocumentList createMockDocumentList() { + SolrDocumentList documents = new SolrDocumentList(); + documents.setNumFound(0); + documents.setStart(0); + return documents; + } + + private SolrDocumentList createMockDocumentListWithData() { + SolrDocumentList documents = new SolrDocumentList(); + documents.setNumFound(2); + documents.setStart(0); + documents.setMaxScore(1.0f); + SolrDocument doc1 = new SolrDocument(); + doc1.setField("id", "book001"); + doc1.setField("name", "Spring Boot in Action"); + doc1.setField("author_ss", List.of("Craig Walls")); + doc1.setField("price", 39.99); + doc1.setField("genre_s", "technology"); + documents.add(doc1); + SolrDocument doc2 = new SolrDocument(); + doc2.setField("id", "book002"); + doc2.setField("name", "Effective Java"); + doc2.setField("author_ss", List.of("Joshua Bloch")); + doc2.setField("price", 44.99); + doc2.setField("genre_s", "technology"); + documents.add(doc2); + return documents; + } + + private List createMockFacetFields() { + FacetField genreFacet = new FacetField("genre_s"); + genreFacet.add("technology", 5); + genreFacet.add("fiction", 3); + FacetField authorFacet = new FacetField("author_ss"); + authorFacet.add("Craig Walls", 2); + authorFacet.add("Joshua Bloch", 1); + return List.of(genreFacet, authorFacet); + } +} diff --git a/src/test/resources/sample-data/books.csv b/src/test/resources/sample-data/books.csv new file mode 100644 index 0000000..248b2f0 --- /dev/null +++ b/src/test/resources/sample-data/books.csv @@ -0,0 +1,11 @@ +id,cat,name,price,inStock,author,series_t,sequence_i,genre_s +0553573403,book,A Game of Thrones,7.99,true,George R.R. Martin,A Song of Ice and Fire,1,fantasy +0553579908,book,A Clash of Kings,7.99,true,George R.R. Martin,A Song of Ice and Fire,2,fantasy +055357342X,book,A Storm of Swords,7.99,true,George R.R. Martin,A Song of Ice and Fire,3,fantasy +0553293354,book,Foundation,7.99,true,Isaac Asimov,Foundation Novels,1,scifi +0812521390,book,The Black Company,6.99,false,Glen Cook,The Chronicles of The Black Company,1,fantasy +0812550706,book,Ender's Game,6.99,true,Orson Scott Card,Ender,1,scifi +0441385532,book,Jhereg,7.95,false,Steven Brust,Vlad Taltos,1,fantasy +0380014300,book,Nine Princes In Amber,6.99,true,Roger Zelazny,the Chronicles of Amber,1,fantasy +0805080481,book,The Book of Three,5.99,true,Lloyd Alexander,The Chronicles of Prydain,1,fantasy +080508049X,book,The Black Cauldron,5.99,true,Lloyd Alexander,The Chronicles of Prydain,2,fantasy \ No newline at end of file