¿Cómo usar Elasticsearch con MongoDB?

152

He visitado muchos blogs y sitios sobre la configuración de Elasticsearch para MongoDB para indexar Colecciones en MongoDB, pero ninguno de ellos fue sencillo.

Explíqueme un proceso paso a paso para instalar Elasticsearch, que debe incluir:

  • configuración
  • correr en el navegador

Estoy usando Node.js con express.js, así que por favor ayuda en consecuencia.

bibin david
fuente
44
Nota: Los ríos están en desuso
abdul qayyum

Respuestas:

287

Esta respuesta debería ser suficiente para configurarlo para seguir este tutorial sobre cómo crear un componente de búsqueda funcional con MongoDB, Elasticsearch y AngularJS .

Si está buscando utilizar la búsqueda facetada con datos de una API, entonces el BirdWatch Repo de Matthiasn es algo que quizás desee ver.

Así es como puede configurar un "clúster" Elasticsearch de un solo nodo para indexar MongoDB para usar en una aplicación NodeJS, Express en una nueva instancia EC2 Ubuntu 14.04.

Asegúrese de que todo esté actualizado.

sudo apt-get update

Instalar NodeJS.

sudo apt-get install nodejs
sudo apt-get install npm

Instalar MongoDB : estos pasos son directamente de los documentos de MongoDB. Elija la versión con la que se sienta cómodo. Me quedo con v2.4.9 porque parece ser la versión más reciente que MongoDB-River admite sin problemas.

Importe la clave pública GPG MongoDB.

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10

Actualiza tu lista de fuentes.

echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list

Obtenga el paquete 10gen.

sudo apt-get install mongodb-10gen

Luego elija su versión si no desea la más reciente. Si está configurando su entorno en una máquina con Windows 7 u 8, manténgase alejado de v2.6 hasta que solucionen algunos errores al ejecutarlo como servicio.

apt-get install mongodb-10gen=2.4.9

Evite que la versión de su instalación de MongoDB se incremente cuando actualice.

echo "mongodb-10gen hold" | sudo dpkg --set-selections

Inicie el servicio MongoDB.

sudo service mongodb start

Los archivos de su base de datos están por defecto en / var / lib / mongo y sus archivos de registro en / var / log / mongo.

Cree una base de datos a través del shell mongo e inserte algunos datos ficticios en él.

mongo YOUR_DATABASE_NAME
db.createCollection(YOUR_COLLECTION_NAME)
for (var i = 1; i <= 25; i++) db.YOUR_COLLECTION_NAME.insert( { x : i } )

Ahora para convertir el MongoDB independiente en un conjunto de réplica .

Primero apaga el proceso.

mongo YOUR_DATABASE_NAME
use admin
db.shutdownServer()

Ahora estamos ejecutando MongoDB como un servicio, por lo que no pasamos la opción "--replSet rs0" en el argumento de la línea de comando cuando reiniciamos el proceso mongod. En cambio, lo ponemos en el archivo mongod.conf.

vi /etc/mongod.conf

Agregue estas líneas, sustituyendo por sus db y rutas de registro.

replSet=rs0
dbpath=YOUR_PATH_TO_DATA/DB
logpath=YOUR_PATH_TO_LOG/MONGO.LOG

Ahora abra el shell mongo nuevamente para inicializar el conjunto de réplicas.

mongo DATABASE_NAME
config = { "_id" : "rs0", "members" : [ { "_id" : 0, "host" : "127.0.0.1:27017" } ] }
rs.initiate(config)
rs.slaveOk() // allows read operations to run on secondary members.

Ahora instale Elasticsearch. Solo estoy siguiendo esta útil Gist .

Asegúrese de que Java esté instalado.

sudo apt-get install openjdk-7-jre-headless -y

Quédese con v1.1.x por ahora hasta que se solucione el error del complemento Mongo-River en v1.2.1.

wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.1.1.deb
sudo dpkg -i elasticsearch-1.1.1.deb

curl -L http://github.com/elasticsearch/elasticsearch-servicewrapper/tarball/master | tar -xz
sudo mv *servicewrapper*/service /usr/local/share/elasticsearch/bin/
sudo rm -Rf *servicewrapper*
sudo /usr/local/share/elasticsearch/bin/service/elasticsearch install
sudo ln -s `readlink -f /usr/local/share/elasticsearch/bin/service/elasticsearch` /usr/local/bin/rcelasticsearch

Asegúrese de que /etc/elasticsearch/elasticsearch.yml tenga habilitadas las siguientes opciones de configuración si solo está desarrollando en un solo nodo por ahora:

cluster.name: "MY_CLUSTER_NAME"
node.local: true

Inicie el servicio Elasticsearch.

sudo service elasticsearch start

Verifica que esté funcionando.

curl http://localhost:9200

Si ves algo como esto, entonces eres bueno.

{
  "status" : 200,
  "name" : "Chi Demon",
  "version" : {
    "number" : "1.1.2",
    "build_hash" : "e511f7b28b77c4d99175905fac65bffbf4c80cf7",
    "build_timestamp" : "2014-05-22T12:27:39Z",
    "build_snapshot" : false,
    "lucene_version" : "4.7"
  },
  "tagline" : "You Know, for Search"
}

Ahora instale los complementos de Elasticsearch para que pueda jugar con MongoDB.

bin/plugin --install com.github.richardwilly98.elasticsearch/elasticsearch-river-mongodb/1.6.0
bin/plugin --install elasticsearch/elasticsearch-mapper-attachments/1.6.0

Estos dos complementos no son necesarios, pero son buenos para probar consultas y visualizar cambios en sus índices.

bin/plugin --install mobz/elasticsearch-head
bin/plugin --install lukas-vlcek/bigdesk

Reinicie Elasticsearch.

sudo service elasticsearch restart

Finalmente indexe una colección de MongoDB.

curl -XPUT localhost:9200/_river/DATABASE_NAME/_meta -d '{
  "type": "mongodb",
  "mongodb": {
    "servers": [
      { "host": "127.0.0.1", "port": 27017 }
    ],
    "db": "DATABASE_NAME",
    "collection": "ACTUAL_COLLECTION_NAME",
    "options": { "secondary_read_preference": true },
    "gridfs": false
  },
  "index": {
    "name": "ARBITRARY INDEX NAME",
    "type": "ARBITRARY TYPE NAME"
  }
}'

Verifique que su índice esté en Elasticsearch

curl -XGET http://localhost:9200/_aliases

Verifique el estado de su clúster.

curl -XGET 'http://localhost:9200/_cluster/health?pretty=true'

Probablemente sea amarillo con algunos fragmentos no asignados. Tenemos que decirle a Elasticsearch con qué queremos trabajar.

curl -XPUT 'localhost:9200/_settings' -d '{ "index" : { "number_of_replicas" : 0 } }'

Verifique el estado del clúster nuevamente. Debería ser verde ahora.

curl -XGET 'http://localhost:9200/_cluster/health?pretty=true'

Ir a jugar.

Donald Gary
fuente
@ Duck5auce tiene alguna idea de cómo obtener el resultado (el resultado de búsqueda elástica) mediante express.js y mostrarlo en el navegador utilizando la plantilla jade o ejs, por ejemplo, como app.get ('search = "google"', function (req , res) {}); y gracias por la maravillosa respuesta
bibin david
@bibindavid Verificaría este recurso. Le guía a través de la creación de un módulo de cliente ES del lado del servidor a través del cual inserta consultas filtradas a través de otros dos módulos personalizados. La representación de los datos todavía se maneja en el cliente, pero debería ser un punto de partida decente. sahan.me/posts/dabbling-in-elasticsearch-part-2-with-nodejs Repositorio de Github ubicado aquí: github.com/sahan/sahan.github.io/tree/master/resources/…
Donald Gary
¿Puedes decirme cuál será mejor mongoosastico o usar mongose ​​y el módulo de búsqueda elástica de manera diferente?
Sudhanshu Gaur
77
Ha pasado un año desde la excelente respuesta de duck5auce. Piense que las personas ahora están usando 10gens [mongo-connector] [1] para sincronizar un clúster MongoDB con ElasticSearch en tiempo real. Sigue el oplog de MongoDB. [1]: github.com/10gen-labs/mongo-connector/wiki/…
Andrew Betts
8
@ duck5auce Actualice esta respuesta, no está actualizada. River ha quedado en desuso
tsturzl
35

El uso de river puede presentar problemas cuando su operación se amplía. River usará una tonelada de memoria cuando esté bajo una operación pesada. Recomiendo implementar sus propios modelos de búsqueda elástica , o si está usando mangosta puede construir sus modelos de búsqueda elástica directamente en eso o usar mongoosastic, que esencialmente lo hace por usted.

Otra desventaja de Mongodb River es que se quedará atrapado usando mongodb 2.4.x branch y ElasticSearch 0.90.x. Comenzará a descubrir que se está perdiendo muchas características realmente agradables, y el proyecto del río mongodb simplemente no produce un producto utilizable lo suficientemente rápido como para mantenerse estable. Dicho esto, el río Mongodb definitivamente no es algo con lo que entraría en producción. Se plantea más problemas de lo que vale. Caerá aleatoriamente la escritura bajo una carga pesada, consumirá mucha memoria y no hay configuración para limitar eso. Además, river no se actualiza en tiempo real, lee los registros de operaciones de mongodb, y esto puede retrasar las actualizaciones por hasta 5 minutos en mi experiencia.

Recientemente tuvimos que reescribir una gran parte de nuestro proyecto, porque es una ocurrencia semanal de que algo sale mal con ElasticSearch. Incluso habíamos ido tan lejos como para contratar a un consultor de Dev Ops, que también está de acuerdo en que es mejor alejarse de River.

ACTUALIZAR: Elasticsearch-mongodb-river ahora es compatible con ES v1.4.0 y mongodb v2.6.x. Sin embargo, es probable que aún tenga problemas de rendimiento en operaciones de inserción / actualización pesadas, ya que este complemento intentará leer los oplogs de mongodb para sincronizar. Si hay muchas operaciones desde que se desbloquea el bloqueo (o el bloqueo), notará un uso de memoria extremadamente alto en su servidor Elasticsearch. Si planea tener una operación grande, river no es una buena opción. Los desarrolladores de ElasticSearch aún recomiendan que administre sus propios índices comunicándose directamente con su API utilizando la biblioteca del cliente para su idioma, en lugar de usar river. Este no es realmente el propósito del río. Twitter-river es un gran ejemplo de cómo se debe usar river. Es esencialmente una excelente manera de obtener datos de fuentes externas,

También considere que mongodb-river se queda atrás en la versión, ya que no es mantenido por ElasticSearch Organization, es mantenido por un tercero. El desarrollo se atascó en la rama v0.90 durante mucho tiempo después del lanzamiento de la v1.0, y cuando se lanzó una versión para la v1.0, no fue estable hasta que elasticsearch lanzó la v1.3.0. Las versiones de Mongodb también se quedan atrás. Es posible que se encuentre en una situación difícil cuando busque pasar a una versión posterior de cada uno, especialmente con ElasticSearch en un desarrollo tan pesado, con muchas características muy anticipadas en camino. Mantenerse al día con el último ElasticSearch ha sido muy importante ya que confiamos en mejorar constantemente nuestra funcionalidad de búsqueda como parte central de nuestro producto.

En general, probablemente obtendrá un mejor producto si lo hace usted mismo. No es tan difícil. Es solo otra base de datos para administrar en su código, y se puede colocar fácilmente en sus modelos existentes sin una refactorización importante.

tsturzl
fuente
¿Tiene un enlace o un consejo donde puedo decir, la indexación de información en el índice autor publicación desde la publicación y autor están en colecciones 2 y enlace a través de referenceone y referencemany
Marcel Djaman
Lea esto para algunos antecedentes elastic.co/guide/en/elasticsearch/guide/current/relations.html
tsturzl
El esto explicaría cómo se inscribe / relacionar los datos elastic.co/guide/en/elasticsearch/guide/current/...
tsturzl
1
Elasticsearch es una base de datos de almacenamiento de documentos, en lugar de una relacional. No es imposible relacionar datos en Elasticsearch, pero es más probable que ocurra la desnormalización, pero se puede administrar con lógica adicional (hay complementos). La forma más común de relacionar datos, como se indica en el enlace anterior, es almacenar una referencia de ID en el documento relativo. Asegúrese de almacenar esta ID en un campo que esté configurado en not_analyzed, de lo contrario tendrá problemas para consultarla, de la forma en que los campos analizados se tokenizan.
tsturzl
4

Encontré mongo-connector útil. Está formado por Mongo Labs (MongoDB Inc.) y se puede usar ahora con Elasticsearch 2.x

Administrador de documentos de Elastic 2.x: https://github.com/mongodb-labs/elastic2-doc-manager

mongo-connector crea una tubería desde un clúster MongoDB a uno o más sistemas de destino, como Solr, Elasticsearch u otro clúster MongoDB. Sincroniza los datos en MongoDB con el destino y luego sigue el oplog de MongoDB, manteniéndose al día con las operaciones en MongoDB en tiempo real. Ha sido probado con Python 2.6, 2.7 y 3.3+. La documentación detallada está disponible en la wiki.

https://github.com/mongodb-labs/mongo-connector https://github.com/mongodb-labs/mongo-connector/wiki/Usage%20with%20ElasticSearch

Lokendra Chauhan
fuente
4

River es una buena solución una vez que desee tener una sincronización casi en tiempo real y una solución general.

Si ya tiene datos en MongoDB y desea enviarlos muy fácilmente a Elasticsearch como "one-shot", puede probar mi paquete en Node.js https://github.com/itemsapi/elasticbulk .

Está utilizando transmisiones Node.js para que pueda importar datos de todo lo que admite transmisiones (es decir, archivos MongoDB, PostgreSQL, MySQL, JSON, etc.)

Ejemplo de MongoDB a Elasticsearch:

Instalar paquetes:

npm install elasticbulk
npm install mongoose
npm install bluebird

Crear script, es decir, script.js:

const elasticbulk = require('elasticbulk');
const mongoose = require('mongoose');
const Promise = require('bluebird');
mongoose.connect('mongodb://localhost/your_database_name', {
  useMongoClient: true
});

mongoose.Promise = Promise;

var Page = mongoose.model('Page', new mongoose.Schema({
  title: String,
  categories: Array
}), 'your_collection_name');

// stream query 
var stream = Page.find({
}, {title: 1, _id: 0, categories: 1}).limit(1500000).skip(0).batchSize(500).stream();

elasticbulk.import(stream, {
  index: 'my_index_name',
  type: 'my_type_name',
  host: 'localhost:9200',
})
.then(function(res) {
  console.log('Importing finished');
})

Envía tus datos:

node script.js

No es extremadamente rápido, pero funciona para millones de registros (gracias a las transmisiones).


fuente
3

Aquí cómo hacer esto en mongodb 3.0. Usé este lindo blog

  1. Instala mongodb.
  2. Crear directorios de datos:
$ mkdir RANDOM_PATH/node1
$ mkdir RANDOM_PATH/node2> 
$ mkdir RANDOM_PATH/node3
  1. Iniciar instancias de Mongod
$ mongod --replSet test --port 27021 --dbpath node1
$ mongod --replSet test --port 27022 --dbpath node2
$ mongod --replSet test --port 27023 --dbpath node3
  1. Configure el conjunto de réplicas:
$ mongo
config = {_id: 'test', members: [ {_id: 0, host: 'localhost:27021'}, {_id: 1, host: 'localhost:27022'}]};    
rs.initiate(config);
  1. Instalación de Elasticsearch:
a. Download and unzip the [latest Elasticsearch][2] distribution

b. Run bin/elasticsearch to start the es server.

c. Run curl -XGET http://localhost:9200/ to confirm it is working.
  1. Instalación y configuración del río MongoDB:

$ bin / plugin --instalar com.github.richardwilly98.elasticsearch / elasticsearch-river-mongodb

$ bin / plugin --instalar elasticsearch / elasticsearch-mapper-attachments

  1. Crea el "Río" y el Índice:

curl -XPUT ' http: // localhost: 8080 / _river / mongodb / _meta ' -d '{"type": "mongodb", "mongodb": {"db": "mydb", "collection": "foo" }, "index": {"name": "name", "type": "random"}} '

  1. Prueba en el navegador:

    http: // localhost: 9200 / _search? q = inicio

Priyanshu Chauhan
fuente
66
ElasticSearch ha dejado de usar plugins de río. Ciertamente, esta no es la mejor manera de mantener un índice de búsqueda.
tsturzl
3

Aquí encontré otra buena opción para migrar sus datos de MongoDB a Elasticsearch. Un demonio go que sincroniza mongodb con elasticsearch en tiempo real. Es el Monstache. Está disponible en: Monstache

Debajo del setp inicial para configurarlo y usarlo.

Paso 1:

C:\Program Files\MongoDB\Server\4.0\bin>mongod --smallfiles --oplogSize 50 --replSet test

Paso 2 :

C:\Program Files\MongoDB\Server\4.0\bin>mongo

C:\Program Files\MongoDB\Server\4.0\bin>mongo
MongoDB shell version v4.0.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 4.0.2
Server has startup warnings:
2019-01-18T16:56:44.931+0530 I CONTROL  [initandlisten]
2019-01-18T16:56:44.931+0530 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2019-01-18T16:56:44.931+0530 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2019-01-18T16:56:44.931+0530 I CONTROL  [initandlisten]
2019-01-18T16:56:44.931+0530 I CONTROL  [initandlisten] ** WARNING: This server is bound to localhost.
2019-01-18T16:56:44.931+0530 I CONTROL  [initandlisten] **          Remote systems will be unable to connect to this server.
2019-01-18T16:56:44.931+0530 I CONTROL  [initandlisten] **          Start the server with --bind_ip <address> to specify which IP
2019-01-18T16:56:44.931+0530 I CONTROL  [initandlisten] **          addresses it should serve responses from, or with --bind_ip_all to
2019-01-18T16:56:44.931+0530 I CONTROL  [initandlisten] **          bind to all interfaces. If this behavior is desired, start the
2019-01-18T16:56:44.931+0530 I CONTROL  [initandlisten] **          server with --bind_ip 127.0.0.1 to disable this warning.
2019-01-18T16:56:44.931+0530 I CONTROL  [initandlisten]
MongoDB Enterprise test:PRIMARY>

Paso 3: Verifique la replicación.

MongoDB Enterprise test:PRIMARY> rs.status();
{
        "set" : "test",
        "date" : ISODate("2019-01-18T11:39:00.380Z"),
        "myState" : 1,
        "term" : NumberLong(2),
        "syncingTo" : "",
        "syncSourceHost" : "",
        "syncSourceId" : -1,
        "heartbeatIntervalMillis" : NumberLong(2000),
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1547811537, 1),
                        "t" : NumberLong(2)
                },
                "readConcernMajorityOpTime" : {
                        "ts" : Timestamp(1547811537, 1),
                        "t" : NumberLong(2)
                },
                "appliedOpTime" : {
                        "ts" : Timestamp(1547811537, 1),
                        "t" : NumberLong(2)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1547811537, 1),
                        "t" : NumberLong(2)
                }
        },
        "lastStableCheckpointTimestamp" : Timestamp(1547811517, 1),
        "members" : [
                {
                        "_id" : 0,
                        "name" : "localhost:27017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 736,
                        "optime" : {
                                "ts" : Timestamp(1547811537, 1),
                                "t" : NumberLong(2)
                        },
                        "optimeDate" : ISODate("2019-01-18T11:38:57Z"),
                        "syncingTo" : "",
                        "syncSourceHost" : "",
                        "syncSourceId" : -1,
                        "infoMessage" : "",
                        "electionTime" : Timestamp(1547810805, 1),
                        "electionDate" : ISODate("2019-01-18T11:26:45Z"),
                        "configVersion" : 1,
                        "self" : true,
                        "lastHeartbeatMessage" : ""
                }
        ],
        "ok" : 1,
        "operationTime" : Timestamp(1547811537, 1),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1547811537, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}
MongoDB Enterprise test:PRIMARY>

Paso 4. Descarga el " https://github.com/rwynn/monstache/releases ". Descomprima la descarga y ajuste su variable PATH para incluir la ruta a la carpeta de su plataforma. Vaya a cmd y escriba "monstache -v" # 4.13.1 Monstache usa el formato TOML para su configuración. Configure el archivo para la migración llamado config.toml

Paso 5

Mi config.toml ->

mongo-url = "mongodb://127.0.0.1:27017/?replicaSet=test"
elasticsearch-urls = ["http://localhost:9200"]

direct-read-namespaces = [ "admin.users" ]

gzip = true
stats = true
index-stats = true

elasticsearch-max-conns = 4
elasticsearch-max-seconds = 5
elasticsearch-max-bytes = 8000000 

dropped-collections = false
dropped-databases = false

resume = true
resume-write-unsafe = true
resume-name = "default"
index-files = false
file-highlighting = false
verbose = true
exit-after-direct-reads = false

index-as-update=true
index-oplog-time=true

Paso 6

D:\15-1-19>monstache -f config.toml

Monstache corriendo ...

Confirmar datos migrados en Elasticsearch

Agregar registro en Mongo

Monstache Capturó el evento y migró los datos a Elasticsearch

Abhijit Bashetti
fuente
3

Dado que el conector mongo ahora parece muerto, mi compañía decidió crear una herramienta para usar flujos de cambio Mongo para generar Elasticsearch.

Nuestros resultados iniciales parecen prometedores. Puede consultarlo en https://github.com/electionsexperts/mongo-stream . Todavía estamos en una etapa temprana de desarrollo, y agradeceríamos sugerencias o contribuciones.

Jud
fuente