"term" type query

Hi all,

First and foremost: I searched the archives and the only post I found which is similar to my issue was this http://elasticsearch-users.115913.n3.nabble.com/Search-query-issue-using-quot-term-quot-and-spaces-td1020831.html

I'm a new user of ElasticSearch and am currently trying to wrap my head around being able to search for moth exact and partial matches.

Partial matches I can do :slight_smile:

The problem I have is exact matches; take for example the following (very simple) records:

{ "name" : "Chris Gedrim" }
{ "name" : "Peter Gedrim" }

Both of which live in the 'test' index with a type of 'people'.

I run the following query (for partial matching):

{
"query" : {
"query_string" : {
"query" : "name:Gedrim"
}
}
}

Which returns:

"hits" : {
"total" : 2,
"max_score" : 0.19178301,
"hits" : [ {
"_index" : "test",
"_type" : "chrisgedrim",
"_id" : "t-eRmndRQ3uwKI4c01v2Aw",
"_score" : 0.19178301, "_source" : {name:"Peter Gedrim"}
}, {
"_index" : "test",
"_type" : "chrisgedrim",
"_id" : "vbWG0Py0SdCSGnW2kfeaZg",
"_score" : 0.19178301, "_source" : {name:"Chris Gedrim"}
} ]
}

All of which is fine.

I then run the following (for an exact match):

{
"query" : {
"term" : {
"name" : "Chris Gedrim"
}
}
}

Which returns:

"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}

From the previously linked-to post I think I should be creating a multi-field mapping thus:

{
"people" : {
"properties" : {
"name" : {
"type" : "multi_field",
"fields" : {
"name" : {"type" : "string", "index" : "analyzed"},
"untouched" : {"type" : "string", "index" : "not_analyzed"}
}
}
}
}
}

Is this correct? If so is there any way of setting all strings to use this mapping?

Also: would the term query above work correctly with this new mapping, or does it need modifying to use the 'untouched' field?

Cheers,

Chris

If you're using the standard parser for the name field, then it will lower-case and split on white space. If you want to search on proper case, then not_analyzed would work or using the multi-field mapping and searching on the untouched field would work.

When index, you need to pick and analyzer based on how you intend to search that field. You can read over the mapping section if you need more information. http://www.elasticsearch.org/guide/reference/mapping/

  • Craig

Craig,

Cheers for the reply, but I've already read the documentation and it doesn't seem to answer my question, hence posting it here.

Just to reiterate my main question:

Can I setup a global mapping for string type fields so that they are both analyzed and not_analyzed ?

Hi Chris

Can I setup a global mapping for string type fields so that they are both
analyzed and not_analyzed ?

If you specify the mapping for any field, it is what you specify.

However, if you want to configure the mapping that is dynamically (ie
automatically) added for a new field, then you can use dynamic
templates:

That said, I think that you should reconsider making all string fields
analyzed and not_analyzed by default. It seems a shotgun approach which
will generate way too many terms

clint

Clinton,

Cheers for the reply, I totally missed the root-object type mapping.

That said, I think that you should reconsider making all string fields
analyzed and not_analyzed by default. It seems a shotgun approach which
will generate way too many terms

I appreciate that having both mappings is a shotgun approach, but there seems no other way of allowing both 'loose' and exact searching… please correct me if I'm wrong though.

Also: is there any way of setting the mapping on an index rather than a type? All of the date fields in our application are either stored yyyy-MM-dd or yyyy-MM-dd HH:mm:ss (ie no 'T' before the time portion, which elastic then treats as a string rather than a date)

Cheers,

Chris

Hi Chris

Cheers for the reply, I totally missed the root-object type mapping.

Yeah, it took me a while to find it too :slight_smile:

I appreciate that having both mappings is a shotgun approach, but there
seems no other way of allowing both 'loose' and exact searching… please
correct me if I'm wrong though.

Sure, but you have string fields for different purposes. Some of them
will contain text which should be analyzed, and some will contain fixed
enum-like values.

When do you want to match this exactly:

    "Sure, but you have string fields for different purposes.  Some
    of  
     them will contain text which should be analyzed, and some
    will  
     contain fixed enum-like values."

So what I'm saying is: don't make them ALL analyzed and not_analzyed.
Use the right mapping for the right field.

Also: is there any way of setting the mapping on an /index/ rather than a
/type/? All of the date fields in our application are either stored
/yyyy-MM-dd/ or /yyyy-MM-dd HH:mm:ss/ (ie no 'T' before the time portion,
which elastic then treats as a string rather than a date)

Have a look at:

clint

One option to do that (make, by default, all string types not analyzed) is to use the dynamic templates option (with match_type set to string) to create a template for string type fields. See here: Elasticsearch Platform — Find real-time answers at scale | Elastic.

On Thursday, July 7, 2011 at 1:04 PM, Clinton Gormley wrote:

Hi Chris

Cheers for the reply, I totally missed the root-object type mapping.

Yeah, it took me a while to find it too :slight_smile:

I appreciate that having both mappings is a shotgun approach, but there
seems no other way of allowing both 'loose' and exact searching… please
correct me if I'm wrong though.

Sure, but you have string fields for different purposes. Some of them
will contain text which should be analyzed, and some will contain fixed
enum-like values.

When do you want to match this exactly:

"Sure, but you have string fields for different purposes. Some
of
them will contain text which should be analyzed, and some
will
contain fixed enum-like values."

So what I'm saying is: don't make them ALL analyzed and not_analzyed.
Use the right mapping for the right field.

Also: is there any way of setting the mapping on an /index/ rather than a
/type/? All of the date fields in our application are either stored
/yyyy-MM-dd/ or /yyyy-MM-dd HH:mm:ss/ (ie no 'T' before the time portion,
which elastic then treats as a string rather than a date)

Have a look at:

Elasticsearch Platform — Find real-time answers at scale | Elastic

clint