1
votes

Why does this ES multi-match query return a 400 error (bad request)?

"query": {
      "multi_match": {
        "query": searchTerms,
        "fields": ["content", "title"],
        "operator": "and"
        }
      },
    size: 100,
    from: 0,
    highlight: {
      fields: {
        "title": {number_of_fragments: 0},
        "content": {number_of_fragments: 10,fragment_size: 300}
      }
    }
  }

I'm using this query in conjunction with AngularJS UI Bootstrap Typeahead code like this

uib-typeahead="query as query._source.ymme for query in getSuggestions($viewValue)" typeahead-on-select="search($item)"

This is my search() function

    $scope.search = function() {
    console.log($scope.searchTerms);
    $scope.currentPage = 0;
    $scope.results.documents = [];
    $scope.isSearching = true;

    return searchService.search($scope.searchTerms, $scope.currentPage).then(function(es_return) {      
      var totalItems = es_return.hits.total;
      var totalTime = es_return.took;
      var numPages = Math.ceil(es_return.hits.total / $scope.itemsPerPage);
      $scope.results.pagination = [];

      for (var i = 1; i <= 100; i++) {
        if(totalItems > 0) 
        $scope.results.totalItems = totalItems;
        $scope.results.queryTime = totalTime;

        $scope.results.pagination = searchService.formatResults(es_return.hits.hits);
        $scope.results.documents = $scope.results.pagination.slice($scope.currentPage, $scope.itemsPerPage);
        }
        }
    ),
    function(error){
      console.log('ERROR: ', error.message);
      $scope.isSearching = false;
    }
  };

I'm not quite sure what is wrong? I'm thinking it has something to do with $scope, but I'm not sure. The query works when I use it Sense plugin for ES and it also works if I just type in a search term instead of selecting it from the autocomplete dropdown.

If it is $scope, what am I missing?

UPDATE All shards failed for phase: [query_fetch] org.elasticsearch.search.SearchParseException: [hugetestindex][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{"query":{"multi_match":{"query":{"_index":"hugetestindex","_type":"doc","_id":"57","_score":3.877801,"_source":{"ymme":"bourne supremacy"}},"fields":["content","title"],"operator":"and"}},"size":100,"from":0,"highlight":{"fields":{"title":{"number_of_fragments":0},"content":{"number_of_fragments":10,"fragment_size":300}}}}]]

UPDATE 2 Object {_index: "hugetestindex", _type: "doc", _id: "56", _score: 2.5276248, _source: Object}

I think that is the problem, instead of a search terms, its receiving "Object"....?

UPDATE 3So basically it goes like this,

[Object, Object, Object, Object, Object]
0: Object
    _id: "229"
    _index: "hugetestindex"
    _score: 3.3071127
    _source: Object
        ymme: "bourne supremacy"
        __proto__: Object
        _type: "doc"
    __proto__: 
Object1: 
Object2: 
Object3: 
Object4: 
Object
    length: 5
__proto__: Array[0]

where "bourne supremacy" is the value of the ymme field in the _source Object, the array at the top with the 5 objects is the es return, es_return.hits.hits - this last hits, is the array.

1
Can you put in your error? Also do you get the error when you type something into your input field for the typeahead or when you select something from the typeahead?Vishal Rao
@VishalRao please look at UPDATE above, the error only occurs when I select from the autocomplete termsuser3125823
Can you put in a console.log() inside search() to display the term sent to it as a parameter? I think the issue may lie there.Vishal Rao
@VishalRao please look at UPDATE 2 above, I don't believe its receiving the actual search term value, it's receiving Objectuser3125823
So you should be deconstructing that object to get your search terms, it will be inside the object in one of its fields, it might be something like object.data.hits.hits or something similar. See if you can log the object onto a console and check its contents.Vishal Rao

1 Answers

0
votes

The way you deconstruct your object is by doing something like the following:

object.data.hits.hits._source.field_name;

The above is only a notation to get the value of a single field, you might need to do a loop for each of those values so maybe something like:

$scope.list = []
for hit in object.data.hits.hits {
    $scope.list.push(hit._source.field);
}
console.log(list);

Then from your HTML you want to use this list by doing an ng-repeat with it or something similar to get each of the terms in the list.

<div ng-repeat="term in list">{{term}}</div>

If you can update your question with how your object looks and what data you want from it, I can update this answer to match it exactly.

UPDATE To match your data structure, I'm assuming you want to extract each of the ymme values from those objects. You need to do the following:

<div ng-repeat="object in es_return.hits.hits">
    {{object._source.ymme}}
</div>

Just make sure "es_return" is a $scope variable so you can access it as above or just do:

$scope.es_return = es_return;

In your Angular code