Como usar o Elasticsearch com o MongoDB?

152

Passei por muitos blogs e sites sobre a configuração do Elasticsearch for MongoDB para indexar coleções no MongoDB, mas nenhum deles foi direto.

Por favor, explique-me um processo passo a passo para instalar o elasticsearch, que deve incluir:

  • configuração
  • executar no navegador

Estou usando o Node.js com o express.js, então ajude de acordo.

bibin david
fonte
4
Nota: os rios estão obsoletos
abdul qayyum 12/0218

Respostas:

287

Esta resposta deve ser suficiente para você seguir este tutorial sobre Construindo um componente de pesquisa funcional com MongoDB, Elasticsearch e AngularJS .

Se você deseja usar a pesquisa facetada com dados de uma API, o BirdWatch Repo da Matthiasn é algo que você pode querer considerar.

Então, aqui está como você pode configurar um "cluster" Elasticsearch de nó único para indexar o MongoDB para uso em um aplicativo NodeJS, Express em uma instância nova do EC2 Ubuntu 14.04.

Verifique se está tudo atualizado.

sudo apt-get update

Instale o NodeJS.

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

Instale o MongoDB - Essas etapas são diretamente dos documentos do MongoDB. Escolha qualquer versão com a qual você se sinta confortável. Estou aderindo à v2.4.9 porque parece ser a versão mais recente que o MongoDB-River suporta sem problemas.

Importe a chave GPG pública do MongoDB.

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

Atualize sua lista de fontes.

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

Obtenha o pacote 10gen.

sudo apt-get install mongodb-10gen

Em seguida, escolha sua versão se você não quiser as mais recentes. Se você estiver configurando seu ambiente em uma máquina com Windows 7 ou 8, fique longe da v2.6 até que eles solucionem alguns erros ao executá-lo como um serviço.

apt-get install mongodb-10gen=2.4.9

Evite que a versão da sua instalação do MongoDB seja aumentada quando você atualiza.

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

Inicie o serviço MongoDB.

sudo service mongodb start

Seus arquivos de banco de dados são padrão para / var / lib / mongo e seus arquivos de log para / var / log / mongo.

Crie um banco de dados através do shell mongo e insira alguns dados fictícios nele.

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

Agora, para converter o MongoDB independente em um conjunto de réplicas .

Primeiro encerre o processo.

mongo YOUR_DATABASE_NAME
use admin
db.shutdownServer()

Agora, estamos executando o MongoDB como um serviço, para que não passemos a opção "--replSet rs0" no argumento da linha de comando quando reiniciarmos o processo mongod. Em vez disso, colocamos no arquivo mongod.conf.

vi /etc/mongod.conf

Adicione essas linhas, substituindo os caminhos db e log.

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

Agora abra o shell mongo novamente para inicializar o 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.

Agora instale o Elasticsearch. Estou apenas seguindo este Gist útil .

Verifique se o Java está instalado.

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

Continue com a v1.1.x por enquanto até que o bug do plugin Mongo-River seja corrigido na 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

Verifique se o /etc/elasticsearch/elasticsearch.yml tem as seguintes opções de configuração ativadas se você estiver desenvolvendo apenas um único nó no momento:

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

Inicie o serviço Elasticsearch.

sudo service elasticsearch start

Verifique se está funcionando.

curl http://localhost:9200

Se você vê algo assim, então você é bom.

{
  "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"
}

Agora instale os plugins do Elasticsearch para que ele possa jogar com o MongoDB.

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

Esses dois plug-ins não são necessários, mas são bons para testar consultas e visualizar alterações em seus índices.

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

Reinicie o Elasticsearch.

sudo service elasticsearch restart

Por fim, indexe uma coleção do 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 se o seu índice está no Elasticsearch

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

Verifique a integridade do seu cluster.

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

Provavelmente é amarelo com alguns fragmentos não atribuídos. Temos que dizer à Elasticsearch com o que queremos trabalhar.

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

Verifique a integridade do cluster novamente. Agora deve estar verde.

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

Vá jogar.

Donald Gary
fonte
@ Duck5auce tem alguma idéia de como obter o resultado (o resultado da pesquisa elástica) pelo express.js e exibir no navegador usando o modelo jade ou ejs, por exemplo, como app.get ('search = "google"', function (req , res) {}); e obrigado pela resposta maravilhosa
bibin david
@bibindavid Eu verificaria este recurso. Ele orienta você na criação de um módulo de cliente ES do servidor, no qual você envia consultas filtradas por meio de dois outros módulos personalizados. A renderização dos dados ainda é tratada no cliente, mas deve ser um ponto de partida decente. sahan.me/posts/dabbling-in-elasticsearch-part-2-with-nodejs repositório no GitHub localizado aqui: github.com/sahan/sahan.github.io/tree/master/resources/...
Donald Gary
Você pode pls me dizer qual será o melhor mongoosástico ou usando o módulo mongose ​​e elasticsearch de maneira diferente ????
Sudhanshu Gaur
7
Faz um ano desde a excelente resposta do duck5auce. Acho que agora as pessoas estão usando 10gens [mongo-connector] [1] para sincronizar um cluster MongoDB com o ElasticSearch em tempo real. Ele segue o oplog do MongoDB. [1]: github.com/10gen-labs/mongo-connector/wiki/…
Andrew Betts
8
@ duck5auce Atualize esta resposta, está desatualizada. Rio foi reprovada
tsturzl
35

O uso do river pode apresentar problemas quando sua operação aumenta. River gastará uma tonelada de memória quando estiver em operação pesada. Eu recomendo a implementação de seus próprios modelos de pesquisa elástica, ou, se você estiver usando o mangusto, poderá criar seus modelos de pesquisa elástica diretamente ou usar o mongo-elástico, que basicamente faz isso por você.

Outra desvantagem do Mongodb River é que você ficará preso usando o mongodb 2.4.x branch e o ElasticSearch 0.90.x. Você começará a descobrir que está perdendo muitos recursos realmente bons, e o projeto mongodb river simplesmente não produz um produto utilizável rápido o suficiente para se manter estável. Dito isto, o rio Mongodb definitivamente não é algo com o qual eu entraria em produção. Colocou mais problemas do que vale a pena. Ele descartará a gravação aleatoriamente sob carga pesada, consumirá muita memória e não há configuração para limitar isso. Além disso, o river não é atualizado em tempo real, ele lê oplogs do mongodb e isso pode atrasar as atualizações por até 5 minutos na minha experiência.

Recentemente, tivemos que reescrever uma grande parte do nosso projeto, porque é uma ocorrência semanal que algo dá errado com o ElasticSearch. Chegamos ao ponto de contratar um consultor de operações de desenvolvimento, que também concorda que é melhor se afastar de River.

ATUALIZAR: O Elasticsearch-mongodb-river agora suporta ES v1.4.0 e mongodb v2.6.x. No entanto, você provavelmente ainda terá problemas de desempenho em operações pesadas de inserção / atualização, pois esse plug-in tentará ler os oplogs do mongodb para sincronizar. Se houver muitas operações desde que a trava (ou a trava é desbloqueada), você notará um uso de memória extremamente alto no servidor de pesquisa elastics. Se você planeja realizar uma grande operação, o rio não é uma boa opção. Os desenvolvedores do ElasticSearch ainda recomendam que você gerencie seus próprios índices, comunicando-se diretamente com a API deles usando a biblioteca do cliente para o seu idioma, em vez de usar o river. Este não é realmente o objetivo do rio. O Twitter-river é um ótimo exemplo de como o rio deve ser usado. É essencialmente uma ótima maneira de obter dados de fontes externas,

Considere também que o mongodb-river fica para trás na versão, pois não é mantido pela ElasticSearch Organization, é mantido por uma terceira parte. O desenvolvimento ficou parado na ramificação da v0.90 por um longo tempo após o lançamento da v1.0 e, quando uma versão da v1.0 foi lançada, ela não era estável até a elasticsearch lançar a v1.3.0. As versões do Mongodb também ficam para trás. Você pode se encontrar em uma situação difícil quando deseja mudar para uma versão posterior de cada uma, especialmente com o ElasticSearch em desenvolvimento tão pesado, com muitos recursos muito aguardados a caminho. Manter-se atualizado sobre o ElasticSearch mais recente tem sido muito importante, pois confiamos muito no aprimoramento constante de nossa funcionalidade de pesquisa como parte essencial do nosso produto.

Ao todo, você provavelmente obterá um produto melhor se o fizer. Não é tão difícil assim. É apenas mais um banco de dados para gerenciar no seu código e pode ser facilmente inserido nos modelos existentes sem grandes refatorações.

tsturzl
fonte
Você tem um link ou um conselho onde posso indexar ou seja, informação do autor em índice de publicação desde a publicação e autor estão em 2 arrecadações e link via referenceone e referencemany
Marcel Djaman
Isso explicaria como você une / relaciona dados elastic.co/guide/en/elasticsearch/guide/current/…
tsturzl
1
O Elasticsearch é um banco de dados de armazenamento de documentos, e não relacional. Não é impossível relacionar dados na pesquisa elástica, mas a desnormalização é mais provável de ocorrer, mas pode ser gerenciada com lógica adicional (existem plugins). A maneira mais comum de relacionar dados, como o estado no link acima, é armazenar uma referência de ID no documento relativo. Certifique-se de armazenar esse ID em um campo definido como not_analyzed, caso contrário você terá problemas para consultá-lo, assim como os campos analisados ​​serão tokenizados.
Tsturzl 18/10/2015
4

Achei o mongo-connector útil. Ele é do Mongo Labs (MongoDB Inc.) e pode ser usado agora com o Elasticsearch 2.x

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

O mongo-connector cria um pipeline de um cluster MongoDB para um ou mais sistemas de destino, como Solr, Elasticsearch ou outro cluster MongoDB. Ele sincroniza os dados no MongoDB com o destino e, em seguida, segue o oplog do MongoDB, acompanhando as operações no MongoDB em tempo real. Foi testado com Python 2.6, 2.7 e 3.3+. Documentação detalhada está disponível no wiki.

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

Lokendra Chauhan
fonte
4

O River é uma boa solução quando você deseja ter uma sincronização quase em tempo real e uma solução geral.

Se você já possui dados no MongoDB e deseja enviá-los com muita facilidade para a Elasticsearch como "one-shot", pode experimentar meu pacote no Node.js https://github.com/itemsapi/elasticbulk .

Ele usa fluxos Node.js para que você possa importar dados de tudo o que suporta fluxos (por exemplo, arquivos MongoDB, PostgreSQL, MySQL, JSON, etc.)

Exemplo para MongoDB para Elasticsearch:

Instale pacotes:

npm install elasticbulk
npm install mongoose
npm install bluebird

Crie um script, por exemplo, 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');
})

Envie seus dados:

node script.js

Não é extremamente rápido, mas está funcionando para milhões de registros (graças aos fluxos).


fonte
3

Aqui como fazer isso no mongodb 3.0. Eu usei esse bom blog

  1. Instale o mongodb.
  2. Crie diretórios de dados:
$ mkdir RANDOM_PATH/node1
$ mkdir RANDOM_PATH/node2> 
$ mkdir RANDOM_PATH/node3
  1. Iniciar instâncias Mongod
$ mongod --replSet test --port 27021 --dbpath node1
$ mongod --replSet test --port 27022 --dbpath node2
$ mongod --replSet test --port 27023 --dbpath node3
  1. Configure o conjunto de réplicas:
$ mongo
config = {_id: 'test', members: [ {_id: 0, host: 'localhost:27021'}, {_id: 1, host: 'localhost:27022'}]};    
rs.initiate(config);
  1. Instalando o 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. Instalando e configurando o MongoDB River:

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

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

  1. Crie o "rio" e o índice:

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

  1. Teste no navegador:

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

Priyanshu Chauhan
fonte
6
O ElasticSearch descontinuou os plugins do river. Certamente, essa não é a melhor maneira de manter um índice de pesquisa.
Tsturzl
3

Aqui encontrei outra boa opção para migrar seus dados do MongoDB para o Elasticsearch. Um daemon go que sincroniza o mongodb com a elasticsearch em tempo real. É o Monstache. Está disponível em: Monstache

Abaixo do setp inicial para configurá-lo e usá-lo.

Passo 1:

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

Passo 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>

Etapa 3: verifique a replicação.

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>

Etapa 4. Baixe o " https://github.com/rwynn/monstache/releases ". Descompacte o download e ajuste sua variável PATH para incluir o caminho para a pasta da sua plataforma. "monstache -v" Vá para cmd e digite # 4.13.1 O Monstache usa o formato TOML para sua configuração. Configure o arquivo para migração chamado config.toml

Etapa 5.

Meu 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

Etapa 6.

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

Monstache em execução ...

Confirmar dados migrados no Elasticsearch

Adicionar registro no Mongo

Monstache Capturou o evento e migra os dados para elasticsearch

Abhijit Bashetti
fonte
3

Como o mongo-connector agora parece morto, minha empresa decidiu criar uma ferramenta para usar os fluxos de mudança do Mongo para produzir no Elasticsearch.

Nossos resultados iniciais parecem promissores. Você pode conferir em https://github.com/electionsexperts/mongo-stream . Ainda estamos no início do desenvolvimento e gostaríamos de receber sugestões ou contribuições.

Jud
fonte