Skip to content

Commit

Permalink
add searchkit, setup express endpoint for searchkit to access Elastic…
Browse files Browse the repository at this point in the history
…search
  • Loading branch information
RyanQuey committed Jun 24, 2020
1 parent 14f450d commit 5f990c8
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 18 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@ This project was bootstrapped with [Create React App](https://github.com/faceboo

## Run in Dev Env

First to start Elassandra on two nodes:
```
docker-compose --project-name test -f ./ci/docker-compose.yml up -d --scale node=1
```

In the project directory, you can run:

### `npm start`

And then, in a different terminal:
### `nodemon app.js --config ./nodemon.json`

Runs the app in the development mode.<br />
Expand Down
68 changes: 62 additions & 6 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,66 @@
var express = require('express');
var path = require('path');
const express = require('express');
const path = require('path');

var indexRouter = require('./routes/index');

var app = express();
const indexRouter = require('./routes/index');
const bodyParser = require('body-parser');
const request = require('request')

process.env.NODE_ENV = process.env.NODE_ENV || "development"
console.log("env:", process.env.NODE_ENV)

const port = process.env.PORT || 8080
const elasticsearchUrl = process.env.ELASTICSEARCH_URL || "http://localhost:9200"
// for cors
const clientUrl = process.env.CLIENT_URL || "http://localhost:3000"

const app = express();

/*
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false })); // for parsing application/x-www-form-urlencoded
*/
app.use(express.json());

app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", clientUrl);
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});


app.use("/flight-search", (req, res) => {
const method = req.method.toLowerCase();
const body = req.body;

const headers = {
'Content-Type': "application/json",
}
const url = `${elasticsearchUrl}${req.originalUrl.replace('/flight-search', "/kibana_sample_data_flights")}`
console.log("method", method)
console.log("url", url)
console.log("body", body)
const options = {
uri: url,
headers,
method: 'POST',
json: body,
};

request(options, (esError, esRes, esResBody) => {

if (esError) {
console.error("***error:***")
console.log(esError)
return next(esError);
} else {
console.log(esRes.statusCode) // 200
console.log(esResBody) // 200

return res.send(esResBody);
}
})
})



app.use(express.static(path.join(__dirname, 'build')));

Expand All @@ -17,6 +69,10 @@ app.get('/ping', function (req, res) {
});

app.use('/', indexRouter);
app.use('*', (req, res, next) => {
console.error("Missed our routes, try again")
next(new Error("This should be a 404"))
});

// error handler
app.use(function(err, req, res, next) {
Expand Down
92 changes: 92 additions & 0 deletions elasticsearch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# ======================== Elasticsearch Configuration =========================
#
# NOTE: Elasticsearch comes with reasonable defaults for most settings.
# Before you set out to tweak and tune the configuration, make sure you
# understand what are you trying to accomplish and the consequences.
#
# The primary way of configuring a node is via this file. This template lists
# the most important settings you may want to configure for a production cluster.
#
# Please consult the documentation for further information on configuration options:
# https://www.elastic.co/guide/en/elasticsearch/reference/index.html
#
# ---------------------------------- Cluster -----------------------------------
#
# Use a descriptive name for your cluster:
#
#cluster.name: my-application
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
#
#node.name: node-1
#
# Add custom attributes to the node:
#
#node.attr.rack: r1
#
# ----------------------------------- Paths ------------------------------------
#
# Path to directory where to store the data (separate multiple locations by comma):
#
#path.data: /path/to/data
#
# Path to log files:
#
#path.logs: /path/to/logs
#
# ----------------------------------- Memory -----------------------------------
#
# Lock the memory on startup:
#
#bootstrap.memory_lock: true
#
# Make sure that the heap size is set to about half the memory available
# on the system and that the owner of the process is allowed to use this
# limit.
#
# Elasticsearch performs poorly when the system is swapping the memory.
#
# ---------------------------------- Network -----------------------------------
#
# Set the bind address to a specific IP (IPv4 or IPv6):
#
#network.host: 192.168.0.1
#
# Set a custom port for HTTP:
#
#http.port: 9200
http.cors.enabled : true
http.cors.allow-origin : "*"
http.cors.allow-methods : OPTIONS, HEAD, GET, POST, PUT, DELETE
http.cors.allow-headers : X-Requested-With,X-Auth-Token,Content-Type, Content-Length

# For more information, consult the network module documentation.
#
# --------------------------------- Discovery ----------------------------------
#
# Pass an initial list of hosts to perform discovery when new node is started:
# The default list of hosts is ["127.0.0.1", "[::1]"]
#
#discovery.zen.ping.unicast.hosts: ["host1", "host2"]
#
# Prevent the "split brain" by configuring the majority of nodes (total number of master-eligible nodes / 2 + 1):
#
#discovery.zen.minimum_master_nodes: 3
#
# For more information, consult the zen discovery module documentation.
#
# ---------------------------------- Gateway -----------------------------------
#
# Block initial recovery after a full cluster restart until N nodes are started:
#
#gateway.recover_after_nodes: 3
#
# For more information, consult the gateway module documentation.
#
# ---------------------------------- Various -----------------------------------
#
# Require explicit names when deleting indices:
#
#action.destructive_requires_name: true
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1",
"request": "^2.88.2",
"searchkit": "^2.4.1-alpha.4"
},
"scripts": {
Expand Down
35 changes: 23 additions & 12 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
NoHits,
HitsStats,
SearchkitComponent,
MovieHitsGridItem,
//MovieHitsGridItem,
SelectedFilters,
MenuFilter,
HierarchicalMenuFilter,
Expand All @@ -24,8 +24,9 @@ import {
} from "searchkit";

import './App.css';
const searchkit = new SearchkitManager("http://demo.searchkit.co/api/movies/")
import FlightHit from './components/FlightHit.js';

const searchkit = new SearchkitManager("http://localhost:8080/flight-search")

function App() {
return (
Expand All @@ -35,20 +36,30 @@ function App() {
<SearchBox
autofocus={true}
searchOnChange={true}
prefixQueryFields={["actors^1","type^2","languages","title^10"]}/>
prefixQueryFields={["Carrier^3", "Dest^3", "DestCityName^3", "DestCountry^2", "DestRegion^2", "DestAirportID^5", "DestWeather", "FlightNum^6", "Origin^3", "OriginCityName^3", "OriginCountry^2", "OriginRegion", "OriginAirportID^5", "OriginWeather"]}
/>
</TopBar>
<LayoutBody>
<SideBar>
<HierarchicalMenuFilter
fields={["type.raw", "genres.raw"]}
title="Categories"
id="categories"/>
fields={["Carrier"]}
title="Carrier"
id="carrier"
/>
<RefinementListFilter
id="actors"
title="Actors"
field="actors.raw"
id="Dest"
title="Destination"
field="Dest"
operator="AND"
size={10}/>
size={10}
/>
<RefinementListFilter
id="Origin"
title="Origin"
field="Origin"
operator="AND"
size={10}
/>
</SideBar>
<LayoutResults>
<ActionBar>
Expand All @@ -63,8 +74,8 @@ function App() {
</ActionBarRow>

</ActionBar>
<Hits mod="sk-hits-grid" hitsPerPage={10} itemComponent={MovieHitsGridItem}
sourceFilter={["title", "poster", "imdbId"]}/>
<Hits mod="sk-hits-grid" hitsPerPage={10} itemComponent={FlightHit}
/>
<NoHits/>
</LayoutResults>
</LayoutBody>
Expand Down
22 changes: 22 additions & 0 deletions src/components/FlightHit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { get } from "lodash";

import {
Hits,
SearchkitComponent,
HitItemProps
} from "searchkit";
import React from 'react'

const FlightHit = (props) => (
<div className={props.bemBlocks.item().mix(props.bemBlocks.container("item"))}>
<div className={props.bemBlocks.item("title")}>{props.result._source.DestAirportID} -> {props.result._source.OriginAirportID}</div>
<div className={props.bemBlocks.item("details")}>
<strong>From:</strong>
<div className={props.bemBlocks.item("Origin")}>{props.result._source.Origin}</div>
<strong>To:</strong>
<div className={props.bemBlocks.item("Dest")}>{props.result._source.Dest}</div>
</div>
</div>
)

export default FlightHit

0 comments on commit 5f990c8

Please sign in to comment.