Jak używać Elasticsearch z MongoDB?


152

Przeszedłem przez wiele blogów i witryn na temat konfigurowania Elasticsearch dla MongoDB w celu indeksowania kolekcji w MongoDB, ale żadna z nich nie była prosta.

Proszę wyjaśnić mi krok po kroku proces instalacji narzędzia Flexiblesearch, który powinien obejmować:

  • konfiguracja
  • uruchomić w przeglądarce

Używam Node.js z express.js, więc proszę o odpowiednią pomoc.


4
Uwaga: rzeki są przestarzałe
abdul qayyum

Odpowiedzi:


287

Ta odpowiedź powinna wystarczyć, aby przygotować się do wykonania tego samouczka Budowanie funkcjonalnego komponentu wyszukiwania za pomocą MongoDB, Elasticsearch i AngularJS .

Jeśli chcesz korzystać z wyszukiwania aspektowego z danymi z interfejsu API , warto zwrócić uwagę na BirdWatch Repo Matthiasna .

Oto jak skonfigurować pojedynczy węzeł „klastra” Elasticsearch do indeksowania bazy danych MongoDB do użytku w aplikacji NodeJS, Express na nowej instancji EC2 Ubuntu 14.04.

Upewnij się, że wszystko jest aktualne.

sudo apt-get update

Zainstaluj NodeJS.

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

Zainstaluj MongoDB - te kroki pochodzą bezpośrednio z dokumentacji MongoDB. Wybierz wersję, w której czujesz się komfortowo. Trzymam się wersji 2.4.9, ponieważ wydaje się, że jest to najnowsza wersja obsługiwana przez MongoDB-River bez problemów.

Zaimportuj publiczny klucz GPG MongoDB.

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

Zaktualizuj listę źródeł.

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

Zdobądź pakiet 10gen.

sudo apt-get install mongodb-10gen

Następnie wybierz swoją wersję, jeśli nie chcesz najnowszej. Jeśli konfigurujesz środowisko na komputerze z systemem Windows 7 lub 8, trzymaj się z daleka od wersji 2.6, dopóki nie naprawią błędów podczas uruchamiania go jako usługi.

apt-get install mongodb-10gen=2.4.9

Zapobiegaj podbijaniu wersji instalacji MongoDB podczas aktualizacji.

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

Uruchom usługę MongoDB.

sudo service mongodb start

Domyślnie pliki baz danych to / var / lib / mongo, a pliki dziennika to / var / log / mongo.

Utwórz bazę danych przez powłokę mongo i umieść w niej fikcyjne dane.

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

Teraz, aby przekonwertować samodzielną MongoDB na zestaw replik .

Najpierw zamknij proces.

mongo YOUR_DATABASE_NAME
use admin
db.shutdownServer()

Teraz uruchamiamy MongoDB jako usługę, więc nie przekazujemy opcji „--replSet rs0” w argumencie wiersza poleceń, gdy ponownie uruchamiamy proces mongod. Zamiast tego umieściliśmy go w pliku mongod.conf.

vi /etc/mongod.conf

Dodaj te wiersze, zastępując ścieżki bazy danych i dziennika.

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

Teraz otwórz ponownie powłokę mongo, aby zainicjować zestaw replik.

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.

Teraz zainstaluj Elasticsearch. Po prostu podążam za tym pomocnym streszczeniem .

Upewnij się, że Java jest zainstalowana.

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

Na razie trzymaj się wersji 1.1.x, dopóki błąd wtyczki Mongo-River nie zostanie naprawiony w wersji 1.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

Upewnij się, że /etc/elasticsearch/elasticsearch.yml ma włączone następujące opcje konfiguracji, jeśli na razie tworzysz tylko na jednym węźle:

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

Uruchom usługę Elasticsearch.

sudo service elasticsearch start

Sprawdź, czy działa.

curl http://localhost:9200

Jeśli widzisz coś takiego, jesteś dobry.

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

Teraz zainstaluj wtyczki Elasticsearch, aby mógł grać z MongoDB.

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

Te dwie wtyczki nie są konieczne, ale są dobre do testowania zapytań i wizualizacji zmian w indeksach.

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

Uruchom ponownie Elasticsearch.

sudo service elasticsearch restart

Na koniec zindeksuj kolekcję z 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"
  }
}'

Sprawdź, czy indeks znajduje się w Elasticsearch

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

Sprawdź stan klastra.

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

Prawdopodobnie jest żółty z kilkoma nieprzypisanymi odłamkami. Musimy powiedzieć Elasticsearch, z czym chcemy pracować.

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

Sprawdź ponownie stan klastra. Teraz powinno być zielone.

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

CHodźmy grać.


@ Duck5auce nie ma pojęcia, jak uzyskać wynik (elastyczny wynik wyszukiwania) przez express.js i wyświetlić w przeglądarce za pomocą szablonu jade lub ejs, na przykład app.get ('search = "google"', function (req , res) {}); i dziękuję za wspaniałą odpowiedź
bibin david

@bibindavid Chciałbym sprawdzić ten zasób. Przeprowadza użytkownika przez proces tworzenia modułu klienta ES po stronie serwera, przez który przepychane są zapytania za pośrednictwem dwóch innych niestandardowych modułów. Renderowanie danych nadal odbywa się na kliencie, ale powinno to być przyzwoity punkt wyjścia. sahan.me/posts/dabbling-in-elasticsearch-part-2-with-nodejs Repozytorium Github zlokalizowane tutaj: github.com/sahan/sahan.github.io/tree/master/resources/…
Donald Gary

Czy możesz mi powiedzieć, który będzie lepszy mongoosastic lub inaczej użyje modułu Mongose ​​i Elasticsearch ????
Sudhanshu Gaur

7
Minął już rok od doskonałej odpowiedzi duck5auce. Sądzę, że ludzie używają teraz 10gens [mongo-connector] [1] do synchronizacji klastra MongoDB z ElasticSearch w czasie rzeczywistym. To koniec z oplog MongoDB. [1]: github.com/10gen-labs/mongo-connector/wiki/…
Andrew Betts

8
@ duck5auce Zaktualizuj tę odpowiedź, jest przestarzała. River został wycofany
tsturzl

35

Korzystanie z rzeki może powodować problemy, gdy Twoja operacja się skaluje. Rzeka zużyje mnóstwo pamięci podczas ciężkich operacji. Polecam zaimplementować własne modele elastycznego wyszukiwania lub jeśli używasz mangusty, możesz zbudować swoje modele elastycznego wyszukiwania bezpośrednio w tym lub użyć mongoosastic, który zasadniczo robi to za Ciebie.

Inną wadą Mongodb River jest to, że utkniesz przy użyciu gałęzi mongodb 2.4.x i ElasticSearch 0.90.x. Zaczynasz odkrywać, że brakuje Ci wielu naprawdę fajnych funkcji, a projekt Mongodb River po prostu nie wytwarza użytecznego produktu wystarczająco szybko, aby był stabilny. To powiedziawszy, rzeka Mongodb zdecydowanie nie jest czymś, z czym bym się zajmował. To stwarzało więcej problemów niż było warte. Losowo upuści zapis pod dużym obciążeniem, zużyje dużo pamięci i nie ma ustawienia, które by to ograniczyło. Dodatkowo, river nie aktualizuje się w czasie rzeczywistym, czyta oplogi z mongodb, co z mojego doświadczenia może opóźnić aktualizacje nawet o 5 minut.

Niedawno musieliśmy przepisać dużą część naszego projektu, ponieważ co tydzień zdarza się, że coś idzie nie tak z ElasticSearch. Posunęliśmy się nawet do zatrudnienia konsultanta Dev Ops, który również zgadza się, że najlepiej będzie wyprowadzić się z River.

AKTUALIZACJA: Elasticsearch-mongodb-river obsługuje teraz ES v1.4.0 i mongodb v2.6.x. Jednak nadal prawdopodobnie napotkasz problemy z wydajnością podczas wykonywania ciężkich operacji wstawiania / aktualizacji, ponieważ ta wtyczka będzie próbowała odczytać oplogs mongodb w celu synchronizacji. Jeśli od momentu odblokowania blokady (lub raczej zatrzasku) jest dużo operacji, zauważysz wyjątkowo wysokie zużycie pamięci na serwerze Elasticsearch. Jeśli planujesz przeprowadzić dużą operację, rzeka nie jest dobrym rozwiązaniem. Twórcy ElasticSearch nadal zalecają zarządzanie własnymi indeksami, komunikując się bezpośrednio z ich interfejsem API za pomocą biblioteki klienta dla Twojego języka, zamiast używać river. Tak naprawdę nie jest to celem rzeki. Rzeka na Twitterze jest doskonałym przykładem tego, jak należy korzystać z rzeki. Jest to doskonały sposób na pozyskiwanie danych ze źródeł zewnętrznych,

Weź również pod uwagę, że mongodb-river pozostaje w tyle w wersji, ponieważ nie jest utrzymywana przez ElasticSearch Organisation, a jest utrzymywana przez osobę trzecią. Rozwój utknął w gałęzi v0.90 przez długi czas po wydaniu wersji 1.0, a kiedy została wydana wersja dla wersji 1.0, nie była stabilna do czasu wypuszczenia wersji 1.3.0 elastsearch. Wersje Mongodb również pozostają w tyle. Możesz znaleźć się w trudnej sytuacji, gdy chcesz przejść do późniejszej wersji każdego z nich, zwłaszcza gdy ElasticSearch jest tak intensywnie rozwijany, a po drodze jest wiele bardzo oczekiwanych funkcji. Śledzenie najnowszej wersji ElasticSearch było bardzo ważne, ponieważ w dużym stopniu polegamy na ciągłym ulepszaniu naszej funkcji wyszukiwania, która jest główną częścią naszego produktu.

Podsumowując, prawdopodobnie otrzymasz lepszy produkt, jeśli zrobisz to sam. To nie jest takie trudne. To tylko kolejna baza danych do zarządzania w kodzie i można ją łatwo upuścić do istniejących modeli bez konieczności przeprowadzania poważnych zmian.


Czy masz link lub poradę, w której mogę zindeksować, tj. Informacje o autorze w indeksie publikacji, ponieważ publikacja i autor znajdują się w 2 kolekcjach i link za pośrednictwem
numeru


To wyjaśniałoby, w jaki sposób łączysz /
łączysz

1
Elasticsearch to baza danych przechowywania dokumentów, a nie relacyjna. Nie jest niemożliwe powiązanie danych w elasticsearch, ale denormalizacja jest bardziej prawdopodobna, ale można nią zarządzać za pomocą dodatkowej logiki (są wtyczki). Najczęstszym sposobem powiązania danych, zgodnie ze stanem w powyższym łączu, jest przechowywanie odniesienia do identyfikatora we względnym dokumencie. Upewnij się, że przechowujesz ten identyfikator w polu, które jest ustawione na not_analyzed, w przeciwnym razie będziesz miał problemy z zapytaniem o to, postępuj zgodnie ze sposobem tokenizacji analizowanych pól.
tsturzl

4

Uważam, że złącze mongo jest przydatne. Pochodzi z Mongo Labs (MongoDB Inc.) i może być teraz używany z Elasticsearch 2.x

Menedżer dokumentów Elastic 2.x: https://github.com/mongodb-labs/elastic2-doc-manager

mongo-connector tworzy potok z klastra MongoDB do co najmniej jednego systemu docelowego, takiego jak Solr, Elasticsearch lub inny klaster MongoDB. Synchronizuje dane w MongoDB z celem, a następnie dostosowuje oplog MongoDB, nadążając za operacjami w MongoDB w czasie rzeczywistym. Został przetestowany z Pythonem 2.6, 2.7 i 3.3+. Szczegółowa dokumentacja jest dostępna na wiki.

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


4

River to dobre rozwiązanie, gdy chcesz mieć synchronizację prawie w czasie rzeczywistym i ogólne rozwiązanie.

Jeśli masz już dane w MongoDB i chcesz je bardzo łatwo wysłać do Elasticsearch, np. „One-shot”, możesz wypróbować mój pakiet w Node.js https://github.com/itemsapi/elasticbulk .

Korzysta ze strumieni Node.js, więc możesz importować dane ze wszystkiego, co obsługuje strumienie (tj. MongoDB, PostgreSQL, MySQL, pliki JSON itp.)

Przykład dla MongoDB do Elasticsearch:

Zainstaluj pakiety:

npm install elasticbulk
npm install mongoose
npm install bluebird

Utwórz skrypt, np. 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');
})

Wyślij swoje dane:

node script.js

Nie jest ekstremalnie szybki, ale działa dla milionów płyt (dzięki strumieniom).


3

Oto jak to zrobić w mongodb 3.0. Skorzystałem z tego fajnego bloga

  1. Zainstaluj mongodb.
  2. Utwórz katalogi danych:
$ mkdir RANDOM_PATH/node1
$ mkdir RANDOM_PATH/node2> 
$ mkdir RANDOM_PATH/node3
  1. Uruchom instancje Mongod
$ mongod --replSet test --port 27021 --dbpath node1
$ mongod --replSet test --port 27022 --dbpath node2
$ mongod --replSet test --port 27023 --dbpath node3
  1. Skonfiguruj zestaw replik:
$ mongo
config = {_id: 'test', members: [ {_id: 0, host: 'localhost:27021'}, {_id: 1, host: 'localhost:27022'}]};    
rs.initiate(config);
  1. Instalowanie 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. Instalowanie i konfigurowanie MongoDB River:

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

$ bin / plugin --install Elasticsearch / flexiblesearch-mapper-attachments

  1. Utwórz „Rzekę” i indeks:

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

  1. Przetestuj w przeglądarce:

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


6
ElasticSearch ma przestarzałe wtyczki do rzeki. Z pewnością nie jest to najlepszy sposób na utrzymanie indeksu wyszukiwania.
tsturzl

3

Tutaj znalazłem kolejną dobrą opcję migracji danych MongoDB do Elasticsearch. Demon go, który synchronizuje mongodb z elastycznym wyszukiwaniem w czasie rzeczywistym. To Monstache. Jest dostępny pod adresem: Monstache

Poniżej początkowego ustawienia, aby go skonfigurować i używać.

Krok 1:

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

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

Krok 3: Sprawdź replikację.

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>

Krok 4. Pobierz plik „ https://github.com/rwynn/monstache/releases ”. Rozpakuj pobrany plik i dostosuj zmienną PATH, aby zawierała ścieżkę do folderu dla Twojej platformy. Przejdź do cmd i wpisz "monstache -v" # 4.13.1 Monstache używa formatu TOML do swojej konfiguracji. Skonfiguruj plik do migracji o nazwie config.toml

Krok 5.

Mój 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

Krok 6.

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

Monstache działa ...

Potwierdź zmigrowane dane w Elasticsearch

Dodaj rekord w Mongo

Monstache Przechwycił zdarzenie i dokonał migracji danych do elastycznego wyszukiwania


3

Ponieważ mongo-łącznik wydaje się teraz martwy, moja firma zdecydowała się zbudować narzędzie do używania strumieni zmian Mongo do wyprowadzania danych do Elasticsearch.

Nasze wstępne wyniki wyglądają obiecująco. Możesz to sprawdzić na https://github.com/electionsexperts/mongo-stream . Wciąż jesteśmy na wczesnym etapie rozwoju i mile widziane są sugestie lub wkład.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.