2014-12-15 12 views
11

Próbuję ustawić ElasticSearch w celu indeksowania treści dla mojej usługi autouzupełniania, korzystając z Sugestii ukończenia w wersji 1.4x. Podążałem za radą od ElasticSearch - You Complete Me i używam Go Client olivere/elastic.ElasticSearch + Go: Błędy indeksu (brak funkcji nazwy)

Moja metoda indeksu wygląda trochę tak:

func IndexVehicle(client *elastic.Client, vehicle Vehicle) (bool, error) { 
    // See if it exists already 
    fetch, err := client.Get(). 
     Index(vehicleIndex). 
     Type("vehicle"). 
     Id(vehicle.Id). 
     Do() 
    if err != nil || fetch.Found { 
     return false, err 
    } 

    vehicleName := fmt.Sprintf("%s %s (%s) %s", vehicle.Make, vehicle.Model, vehicle.Model_year, vehicle.Primary_fuel) 

    suggest := elastic.NewSuggestField() 
    suggest.Input(vehicle.Make, vehicle.Model, vehicle.Primary_fuel, vehicle.Model_year). 
     Output(vehicleName). 
     Payload(vehicle) 

    // Go forth and save 
    put, err := client.Index(). 
     Index(vehicleIndex). 
     Type("vehicle"). 
     Id(vehicle.Id). 
     Debug(true).Pretty(true). 
     BodyJson(indexBody{Name: vehicleName, Suggest: suggest}). 
     Do() 
    if err != nil { 
     return false, err 
    } 
    return put.Created, nil 
} 

Teraz to, co jest dziwne, jest to, że niektóre z moich testów ta metoda działa dobrze i przedmioty będą indeksowane. W innych badaniach po przetarciu i odbudowy indeksu test nie powiedzie się:

Wcześniejsze testy wyglądać w debug:

2014/12/15 14:11:37 PUT /vehicle/vehicle/369f96459b340507c4688740da3bfe1a?pretty=true HTTP/1.1 
Host: localhost:9200 
User-Agent: elastic/1.3.1 (darwin-amd64) 
Transfer-Encoding: chunked 
Accept: application/json 
Content-Type: application/json 
Accept-Encoding: gzip 

{"name":"American Motors Corporation Eagle 4WD (1986) regular","suggest":{"input":["American Motors Corporation","Eagle 4WD","regular","1986"],"output":"American Motors Corporation Eagle 4WD (1986) regular","payload":{"make":"American Motors Corporation","model_year":"1986","model":"Eagle 4WD","primary_fuel":"regular","vehicle_class":"Special Purpose Vehicle 4WD","transmission":"Automatic 3-spd","displacement":"4.2","drive":"4-Wheel or All-Wheel Drive","city_mpg":"15.0","highway_mpg":"19.0","comb_mpg":"17.0"}}} 

2014/12/15 14:11:37 HTTP/1.1 201 Created 
Content-Length: 134 
Content-Type: application/json; charset=UTF-8 

{ 
    "_index" : "vehicle", 
    "_type" : "vehicle", 
    "_id" : "369f96459b340507c4688740da3bfe1a", 
    "_version" : 1, 
    "created" : true 
} 

Ale w późniejszych testach, robiąc to samo prowadzi do błędów. err wrócił z IndexVehicle() w późniejszych testach jest:

E 
Errors: 

    * /Users/phil/go/src/github.com/ride/autocomplete/vehicle_test.go 
    Line 79: - elastic: Error 400: ElasticsearchIllegalArgumentException[No feature for name [vehicle]] 
    goroutine 245 [running]: 
    github.com/ride/autocomplete.func·033() 
    /Users/phil/go/src/github.com/ride/autocomplete/vehicle_test.go:79 +0x249 
    github.com/ride/autocomplete.useIndex(0x499e98) 
    /Users/phil/go/src/github.com/ride/autocomplete/test_helper.go:18 +0x55 
    github.com/ride/autocomplete.func·034() 
    /Users/phil/go/src/github.com/ride/autocomplete/vehicle_test.go:96 +0x2a 
    github.com/jtolds/gls._m(0x0, 0xc2080ae9e0) 
    /Users/phil/go/src/github.com/jtolds/gls/stack_tags.go:70 +0x32 
    github.com/jtolds/gls.markS(0x0, 0xc2080ae9e0) 
    /Users/phil/go/src/github.com/jtolds/gls/stack_tags.go:21 +0x32 
    github.com/jtolds/gls.addStackTag(0x0, 0xc2080ae9e0) 
    /Users/phil/go/src/github.com/jtolds/gls/stack_tags.go:18 +0x3e 
    github.com/jtolds/gls.(*ContextManager).SetValues(0xc20801e080, 0xc2080b31d0, 0xc2080ae9e0) 
    /Users/phil/go/src/github.com/jtolds/gls/context.go:98 +0x503 
    github.com/ride/autocomplete.TestSearchForVehicles(0xc20806a480) 
    /Users/phil/go/src/github.com/ride/autocomplete/vehicle_test.go:97 +0x243 
    testing.tRunner(0xc20806a480, 0x5be890) 
    /opt/boxen/homebrew/Cellar/go/1.4/libexec/src/testing/testing.go:447 +0xbf 
    created by testing.RunTests 
    /opt/boxen/homebrew/Cellar/go/1.4/libexec/src/testing/testing.go:555 +0xa8b 

    goroutine 1 [chan receive]: 
    testing.RunTests(0x49a078, 0x5be800, 0x7, 0x7, 0x67c001) 
    /opt/boxen/homebrew/Cellar/go/1.4/libexec/src/testing/testing.go:556 +0xad6 
    testing.(*M).Run(0xc2080463c0, 0x5c9b20) 
    /opt/boxen/homebrew/Cellar/go/1.4/libexec/src/testing/testing.go:485 +0x6c 
    main.main() 
    github.com/ride/autocomplete/_test/_testmain.go:64 +0x1d5 

    goroutine 208 [chan receive]: 
    github.com/olivere/elastic.(*Client).pinger(0xc208106d40) 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:79 +0x6b 
    created by github.com/olivere/elastic.NewClient 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:60 +0x26e 

    goroutine 248 [runnable]: 
    net/http.(*persistConn).readLoop(0xc20802e4d0) 
    /opt/boxen/homebrew/Cellar/go/1.4/libexec/src/net/http/transport.go:928 +0x9ce 
    created by net/http.(*Transport).dialConn 
    /opt/boxen/homebrew/Cellar/go/1.4/libexec/src/net/http/transport.go:660 +0xc9f 

    goroutine 98 [chan receive]: 
    github.com/olivere/elastic.(*Client).pinger(0xc208033e00) 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:79 +0x6b 
    created by github.com/olivere/elastic.NewClient 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:60 +0x26e 

    goroutine 17 [syscall, locked to thread]: 
    runtime.goexit() 
    /opt/boxen/homebrew/Cellar/go/1.4/libexec/src/runtime/asm_amd64.s:2232 +0x1 

    goroutine 44 [chan receive]: 
    github.com/olivere/elastic.(*Client).pinger(0xc2080332c0) 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:79 +0x6b 
    created by github.com/olivere/elastic.NewClient 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:60 +0x26e 

    goroutine 249 [select]: 
    net/http.(*persistConn).writeLoop(0xc20802e4d0) 
    /opt/boxen/homebrew/Cellar/go/1.4/libexec/src/net/http/transport.go:945 +0x41d 
    created by net/http.(*Transport).dialConn 
    /opt/boxen/homebrew/Cellar/go/1.4/libexec/src/net/http/transport.go:661 +0xcbc 

    goroutine 54 [chan receive]: 
    github.com/olivere/elastic.(*Client).pinger(0xc208032f80) 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:79 +0x6b 
    created by github.com/olivere/elastic.NewClient 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:60 +0x26e 

    goroutine 76 [chan receive]: 
    github.com/olivere/elastic.(*Client).pinger(0xc208032e00) 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:79 +0x6b 
    created by github.com/olivere/elastic.NewClient 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:60 +0x26e 

    goroutine 250 [chan receive]: 
    github.com/olivere/elastic.(*Client).pinger(0xc208106c40) 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:79 +0x6b 
    created by github.com/olivere/elastic.NewClient 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:60 +0x26e 

    goroutine 120 [chan receive]: 
    github.com/olivere/elastic.(*Client).pinger(0xc208106b00) 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:79 +0x6b 
    created by github.com/olivere/elastic.NewClient 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:60 +0x26e 

    goroutine 142 [chan receive]: 
    github.com/olivere/elastic.(*Client).pinger(0xc208106e00) 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:79 +0x6b 
    created by github.com/olivere/elastic.NewClient 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:60 +0x26e 

    goroutine 164 [chan receive]: 
    github.com/olivere/elastic.(*Client).pinger(0xc208106b80) 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:79 +0x6b 
    created by github.com/olivere/elastic.NewClient 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:60 +0x26e 

    goroutine 186 [chan receive]: 
    github.com/olivere/elastic.(*Client).pinger(0xc208106d00) 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:79 +0x6b 
    created by github.com/olivere/elastic.NewClient 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:60 +0x26e 

    goroutine 230 [chan receive]: 
    github.com/olivere/elastic.(*Client).pinger(0xc208106dc0) 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:79 +0x6b 
    created by github.com/olivere/elastic.NewClient 
    /Users/phil/go/src/github.com/olivere/elastic/client.go:60 +0x26e 

Prawdopodobnie bardziej istotną częścią tego backtrace jest taka:

Błąd 400: ElasticsearchIllegalArgumentException [No cecha dla imienia [pojazdu]]

Więc, nie jestem pewien, co tu jest nie tak. Mam 1 sekundowy limit czasu na indeksie, ponieważ ten klient nie obsługuje logiki "czekać na zielony" [jeszcze].

func ResetVehicleIndex(client *elastic.Client) (err error) { 

    if _, err = client.DeleteIndex(vehicleIndex).Do(); err != nil { 
     return 
    } 
    if _, err = EnsureVehicleIndex(client); err != nil { 
     return 
    } 

    // TODO: This is awful. Switch to "wait for green" when elastic client supports it 
    time.Sleep(time.Second * 1) 

    return nil 
} 

ten pracował dla większości innych badań, jak elasticsearch wydaje się przygotować na drugi lub tak, ale badania te są konsekwentnie erroring bez względu na czas oczekiwania w tym kawałku kodu.

Wszelkie pomysły? Być może będę musiał edytować pytanie, aby dodać więcej kodu lub lepsze wyjaśnienia, ale szybko odpowiem na wszelkie pytania, zwłaszcza jeśli wyślesz mi wiadomość na Twitterze @philsturgeon. Naprawdę to utknąłem.

Odpowiedz

10

Ten wyjątek to only triggered in one place, który występuje podczas wywoływania funkcji API Pobierz indeks. Co oznacza identyfikator pojazdu musi być null tutaj:

fetch, err := client.Get(). 
     Index(vehicleIndex). 
     Type("vehicle"). 
     Id(vehicle.Id).  //<-- this 
     Do() 

Próbujesz zrobić get Document API, które towarzyszą mu format GET /{index}/{type}/{id}. Jednak klient nie rozróżnia połączeń Get Document i Get Index API ... i nie sprawdza, czy parametry nie mają wartości NULL.

Więc jeśli zerowy vehicle.Id jest przekazywany do metody GET, Twój końcowy URL rzeczywiście będzie GET /{index}/{type}/

Z punktu Elasticsearch widzenia, to nie jest już Get Dokument wywołanie API ... to rzeczywiście Get Index połączenie, które ma następujący format: GET /{index}/{feature}. Może to być jeden z następujących: _settings, _mappings, _aliases lub _warmers.

Ponieważ vehicle nie jest jedną z tych funkcji, ES rzuca wyjątek i wypluwa.Można to sprawdzić za pomocą konsoli:

curl -XGET localhost:9200/my_index/vehicle/

+0

Doskonałość! Tak, to był gówniany kod, w którym jedna metoda ustawiała identyfikator, a inna metoda nie. Zmieniam rzeczy, aby utworzyć metodę 'GetId()', więc zawsze będzie istnieć. Dziękuję bardzo! –

+0

Chętnie pomogę, cieszę się, że to łatwa łatka! :) – Zach

0

Tylko dla kompletności: Miałem ten sam błąd, kiedy zainicjowana moje metody żądania z „postu” zamiast „POST”

tak:

req, _ := http.NewRequest("post", url, query) 
// returns: Error 400: ElasticsearchIllegalArgumentException[No feature for name [_bulk]] 
req, _ := http.NewRequest("POST", url, query) 
// works just fine 
Powiązane problemy