Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi term search #14

Closed
Mattchewone opened this issue Apr 24, 2017 · 6 comments
Closed

Multi term search #14

Mattchewone opened this issue Apr 24, 2017 · 6 comments
Assignees

Comments

@Mattchewone
Copy link
Contributor

Steps to reproduce

Trying to get results by using multi-$phrase search using this query:

?tags.name[$phrase]=rock&tags.name[$phrase]=pop

I am wanting to find all items which have both rock and pop as tags

Here is the data structure in Elasticsearch:

{
  "title": "Track One",
  "description": "description",
  "slug": "track-one",
  "updatedAt": "2017-04-24T20:29:38.178Z",
  "createdAt": "2017-04-24T20:29:38.178Z",
  "tags": [
	{
	  "_id": "58fe600db684ab640b68eb83",
	  "name": "pop",
	  "parent": "58fe5fbfdf4b3863eae06cd1",
	  "slug": "pop",
	  "updatedAt": "2017-04-24T20:29:01.251Z",
	  "createdAt": "2017-04-24T20:29:01.251Z"
	},
	{
	  "_id": "58fe5fc9df4b3863eae06cd2",
	  "name": "rock",
	  "parent": "58fe5fbfdf4b3863eae06cd1",
          "slug": "rock",
	  "updatedAt": "2017-04-24T20:27:53.873Z",
	  "createdAt": "2017-04-24T20:27:53.873Z"
	},
	{
	  "_id": "58fe5fc9df4b3863eae06cd2",
	  "name": "chill",
	  "parent": "58fe5fbfdf4b3863eae06cd1",
          "slug": "chill",
	  "updatedAt": "2017-04-24T20:27:53.873Z",
	  "createdAt": "2017-04-24T20:27:53.873Z"
	}
  ]
}

Expected behavior

I would expect it to build query and find for both the $phrased terms.

Actual behavior

I get this error [illegal_state_exception] Can't get text on a START_ARRAY at 1:49

System configuration

feathers@2.1.1
feathers-elasticsearch@0.2.2

@daffl
Copy link
Member

daffl commented May 3, 2017

@jciolek Any thoughts on this?

@jciolek
Copy link
Collaborator

jciolek commented May 3, 2017

Apologies for the delay. Ok, so here's what seems to be happening. First of all the query string:

?tags.name[$phrase]=rock&tags.name[$phrase]=pop

gets parsed by qs to { 'tags.name': { '$phrase': [ 'rock', 'pop' ] } } and rightly so.

Now, $phrase does not deal with arrays in any special way currently - it passes the value it got from the query as is to Elasticsearch. The latter does not expect an array in the context of the match_phrase query, and so it throws an error.

I think it is a very good use case, and I am going to make some subtle changes to support it. I am thinking of adding array support to $prefix, $match, $phrase and $phrase_prefix, as all of them would benefit.

On a separate note, regarding your particular data structure @Mattchewone, I am wondering if you wouldn't benefit from having keyword instead of text mapping for the tag names. You could then use filter terms query $in which is also faster.

@Mattchewone
Copy link
Contributor Author

@jciolek Thanks very much for looking in to this.

I am new to Elasticsearch and understanding the mappings I am still trying to get to grips with.

Would having keyword mapping work for an array of objects? Would you be kind enough to show a small example to give me something to start with?

Many thanks

@jciolek
Copy link
Collaborator

jciolek commented May 3, 2017

@Mattchewone Not a problem.

So in your case, the query string would be:

?tags.name[$in]=rock&tags.name[$in]=pop

Which translates to an Elasticsearch terms query in filter context:

{
  "query": {
    "bool": {
      "filter": [
        { "terms": { "tags.name": ["rock", "pop"] } }
      ]
    }
  }
}

You can also have a look at the queries fired by https://hacker-search.net/, which uses feathers-elasticsearch. Specifically meta.type is using the $in operator.

I hope that helps.

@jciolek
Copy link
Collaborator

jciolek commented May 3, 2017

Right, so I have read your original issue again and I gather what I just said above is probably not exactly what you are after. I understand you want ALL of the values to be present, not just some. I am working on it.

@daffl
Copy link
Member

daffl commented May 6, 2017

Closed via #16

@daffl daffl closed this as completed May 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants