From f0efb8cdea549964cdcdbf0bd817d04dba0fe968 Mon Sep 17 00:00:00 2001 From: Shay Banon Date: Thu, 24 Nov 2011 13:59:10 +0200 Subject: [PATCH] Using _parent:123 in a query string query fails to fetch docs, closes #1497. --- .../mapper/internal/ParentFieldMapper.java | 32 +++++++++++++++++++ .../elasticsearch/index/search/UidFilter.java | 7 ++-- .../child/SimpleChildQuerySearchTests.java | 24 ++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java index ed56371b350..a4be699ff3b 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java @@ -22,6 +22,11 @@ package org.elasticsearch.index.mapper.internal; import org.apache.lucene.document.Field; import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.Term; +import org.apache.lucene.search.ConstantScoreQuery; +import org.apache.lucene.search.Filter; +import org.apache.lucene.search.PublicTermsFilter; +import org.apache.lucene.search.Query; +import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Strings; import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -34,6 +39,7 @@ import org.elasticsearch.index.mapper.ParseContext; import org.elasticsearch.index.mapper.RootMapper; import org.elasticsearch.index.mapper.Uid; import org.elasticsearch.index.mapper.core.AbstractFieldMapper; +import org.elasticsearch.index.query.QueryParseContext; import java.io.IOException; import java.util.Map; @@ -174,6 +180,32 @@ public class ParentFieldMapper extends AbstractFieldMapper implements Inter return value; } + @Override public Query fieldQuery(String value, @Nullable QueryParseContext context) { + if (context == null) { + return super.fieldQuery(value, context); + } + return new ConstantScoreQuery(fieldFilter(value, context)); + } + + @Override public Filter fieldFilter(String value, @Nullable QueryParseContext context) { + if (context == null) { + return super.fieldFilter(value, context); + } + // we use all types, cause we don't know if its exact or not... + PublicTermsFilter filter = new PublicTermsFilter(); + for (String type : context.mapperService().types()) { + filter.addTerm(names.createIndexNameTerm(Uid.createUid(type, value))); + } + return filter; + } + + /** + * We don't need to analyzer the text, and we need to convert it to UID... + */ + @Override public boolean useFieldQueryWithQueryString() { + return true; + } + public Term term(String type, String id) { return term(Uid.createUid(type, id)); } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/UidFilter.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/UidFilter.java index 212cf514ffe..6ad8088daf7 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/UidFilter.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/UidFilter.java @@ -33,19 +33,20 @@ import org.elasticsearch.index.mapper.Uid; import org.elasticsearch.index.mapper.internal.UidFieldMapper; import java.io.IOException; -import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Set; +import java.util.TreeSet; public class UidFilter extends Filter { - private final List uids; + private final Set uids; private final BloomCache bloomCache; public UidFilter(Collection types, List ids, BloomCache bloomCache) { this.bloomCache = bloomCache; - this.uids = new ArrayList(types.size() * ids.size()); + this.uids = new TreeSet(); for (String type : types) { for (String id : ids) { uids.add(UidFieldMapper.TERM_FACTORY.createTerm(Uid.createUid(type, id))); diff --git a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/child/SimpleChildQuerySearchTests.java b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/child/SimpleChildQuerySearchTests.java index e1596a5afe3..084f9368771 100644 --- a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/child/SimpleChildQuerySearchTests.java +++ b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/child/SimpleChildQuerySearchTests.java @@ -104,6 +104,30 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests { assertThat(searchResponse.hits().getAt(1).id(), anyOf(equalTo("c1"), equalTo("c2"))); assertThat(searchResponse.hits().getAt(1).field("_parent").value().toString(), equalTo("p1")); + searchResponse = client.prepareSearch("test") + .setQuery(termQuery("_parent", "p1")) + .addFields("_parent") + .execute().actionGet(); + assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0)); + assertThat(searchResponse.failedShards(), equalTo(0)); + assertThat(searchResponse.hits().totalHits(), equalTo(2l)); + assertThat(searchResponse.hits().getAt(0).id(), anyOf(equalTo("c1"), equalTo("c2"))); + assertThat(searchResponse.hits().getAt(0).field("_parent").value().toString(), equalTo("p1")); + assertThat(searchResponse.hits().getAt(1).id(), anyOf(equalTo("c1"), equalTo("c2"))); + assertThat(searchResponse.hits().getAt(1).field("_parent").value().toString(), equalTo("p1")); + + searchResponse = client.prepareSearch("test") + .setQuery(queryString("_parent:p1")) + .addFields("_parent") + .execute().actionGet(); + assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0)); + assertThat(searchResponse.failedShards(), equalTo(0)); + assertThat(searchResponse.hits().totalHits(), equalTo(2l)); + assertThat(searchResponse.hits().getAt(0).id(), anyOf(equalTo("c1"), equalTo("c2"))); + assertThat(searchResponse.hits().getAt(0).field("_parent").value().toString(), equalTo("p1")); + assertThat(searchResponse.hits().getAt(1).id(), anyOf(equalTo("c1"), equalTo("c2"))); + assertThat(searchResponse.hits().getAt(1).field("_parent").value().toString(), equalTo("p1")); + // TOP CHILDREN QUERY