1

I have a Elasticsearch setup which will allow user to search indexes as wild cards.

array:3 [
 "index" => "users"
 "type" => "user"
 "body" => array:4 [
 "from" => 0
 "size" => 25
 "sort" => array:1 [
  1 => array:1 [
    "order" => "asc"
  ]
]
"query" => array:1 [
  "bool" => array:1 [
    "should" => array:1 [
      0 => array:1 [
        0 => array:1 [
          "wildcard" => array:1 [
            "full_name" => "john doe"
          ]
        ]
      ]
    ]
  ]
]
]
]

when I pass this array to search function, it is returning an empty array. But there is a document related to "John Doe" and when I run "full_name" => "john" search is returning the document.

I feel that the problem is with the space.

{
"users": {
"user": {
  "properties": {

    "address": {
      "type": "string"
    },
    "full_name": {
      "type": "string"
    },
    "industry_name": {
      "type": "string"
    }
  }
}

} }

Dam Forums
  • 240
  • 2
  • 10
  • 23
  • May you share index mapping? – Rob Jun 23 '15 at 12:27
  • Did you tried the `and` operator? – fjcero Jun 23 '15 at 14:06
  • @Rob:I have added the index mapping – Dam Forums Jun 24 '15 at 02:51
  • @DamForums thank you for your update, but you posted search hit, not index mapping. This is how you can retrive it https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-mapping.html – Rob Jun 24 '15 at 06:10
  • @Rob:I have put the mapping.i found this link with saying that i should try changing index into not_analyzed.but i cant figure out to do it http://stackoverflow.com/questions/30113753/elastic-search-wildcard-search-with-spaces?rq=1 – Dam Forums Jun 24 '15 at 06:41

3 Answers3

1

Assuming field full_name is analyzed by elasticsearch.

The problem in your case is fact that wildcard query doesn't analyze search string

Matches documents that have fields matching a wildcard expression (not analyzed).

In you case it means, that elasticsearch stored john and doe tokens in inverted index, but wildcard query is searching for john doe token, and it fails.

What you can do about this:

  1. Change index mapping, so full_name filed is not analyzed anymore. Note: you will have to search for John Doe to get match, because value wasn't analyzed so john doe won't match.
  2. You can improve first solution, just by leaving full_name analyzed, but with custom analyzer(wildcard, lowercase). It will allow you to search for text john doe or John Doe.

    {
        "settings" : {
            "index" : {
                "analysis" : {
                    "analyzer" : {
                        "lowercase_analyzer" : {
                            "tokenizer" : "keyword",
                            "filter" : [
                                "lowercase"
                            ],
                            "type" : "custom"
                        }
                    }
                }
            }
        },
        "mappings" : {
            "user" : {
                "properties" : {
                    "id" : {
                        "type" : "integer"
                    },
                    "fullName" : {
                        "analyzer" : "lowercase_analyzer",
                        "type" : "string"
                    }
                }
            }
        }
    }
    
  3. You can take advantage of multi field, and search against raw field.

    "full_name.raw" => "John Doe"
    

Hope it will help you handle your use case.

UPDATE

Here you can find more information how to control index mapping.

Rob
  • 9,664
  • 3
  • 41
  • 43
  • How to change the field into not analyzed? – Dam Forums Jun 24 '15 at 06:45
  • @DamForums how do you create index, or you just don't and index is created when the first document was indexed? – Rob Jun 24 '15 at 06:52
  • @DamForums sorry I'm not a php guy, but maybe this link will help you handle this https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/_index_operations.html#_create_an_index_2 – Rob Jun 24 '15 at 06:53
  • :yes when first document is created then index is created. – Dam Forums Jun 24 '15 at 06:54
  • @DamForums so I guess you have to create index explicitly, before you will index first document. Hope my previous link will point you a way. – Rob Jun 24 '15 at 06:56
  • fields should be 'analyzer' => 'standard' or 'analyzer' => 'not_analyzed'?because the second parameter throws an error.first is not returning the document – Dam Forums Jun 24 '15 at 07:34
  • @DamForums 'index' => 'not_analyzed' – Rob Jun 24 '15 at 07:43
  • i used that one and this is the mapping i get. "full_name": { "type": "string", "index": "not_analyzed", "omit_norms": true, "index_options": "docs" }, but still not returning the correct doc – Dam Forums Jun 24 '15 at 07:45
  • @DamForums document contains "john doe" or "John Doe". Just to confirm, you are searching for "john doe"? – Rob Jun 24 '15 at 07:48
  • Document contain: John Doe and my search parameter is John D or John Doe or john doe.and at the time of searching i convert the value into lowercase. – Dam Forums Jun 24 '15 at 07:50
  • indexed token is John Doe and you are searching for john doe, so this is why you don't get match. Maybe try to use my second solution, I guess it's much more flexible, so you will be able to pass "john doe" or "John Doe", and you will get result. I'll update my answer with index mapping. – Rob Jun 24 '15 at 07:54
  • @DamForums check my update for second solution, hope it helps this time. – Rob Jun 24 '15 at 08:01
  • :will check it and get back to u.thanks for the support through out – Dam Forums Jun 24 '15 at 08:12
  • :now i cant create the index.gives me an error.MapperParsingException[Analyzer [lowercase_analyzer] not found for field [address]].may be something to do with my code? – Dam Forums Jun 24 '15 at 08:36
  • Looks like you didn't setup lowercase_analyzer in index settings. – Rob Jun 24 '15 at 08:51
  • :i have added the index settings. – Dam Forums Jun 24 '15 at 08:55
  • Only chance to say something more about your issue in this case is to see how do you create the index. – Rob Jun 24 '15 at 08:58
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/81375/discussion-between-dam-forums-and-rob). – Dam Forums Jun 24 '15 at 08:59
  • First methods works fine. Thanks Rob for the support. – Dam Forums Jul 07 '15 at 03:31
0

I think standard tokenizer will be applied by default.

In that case, it will consider the text john doe as phrase.

So try phrase search

"full_name" => "\"john doe\""
Pandiyan Cool
  • 6,381
  • 8
  • 51
  • 87
0

If you want to consider spaces you could do something like:

{
    "match" : {
         "full_name" : {
            "query" : "john doe",
            "operator" : "and",
            "zero_terms_query": "all"
        }
    }
}

check this: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html

fjcero
  • 156
  • 2
  • 14