Skip to content

Commit

Permalink
Merge pull request #2008 from codingwhatever/regex-search-query
Browse files Browse the repository at this point in the history
Regex search query
  • Loading branch information
himanshug committed Dec 3, 2015
2 parents d02be61 + 596b7eb commit 0eab841
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 1 deletion.
12 changes: 12 additions & 0 deletions docs/content/querying/searchqueryspec.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,16 @@ If any part of a dimension value contains the value specified in this search que
"case_sensitive" : true,
"value" : "some_value"
}
```

RegexSearchQuerySpec
----------------------------------

If any part of a dimension value contains the pattern specified in this search query spec, a "match" occurs. The grammar is:

```json
{
"type" : "regex",
"pattern" : "some_pattern"
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Licensed to Metamarkets Group Inc. (Metamarkets) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Metamarkets licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package io.druid.query.search.search;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Preconditions;
import com.metamx.common.StringUtils;

import java.nio.ByteBuffer;
import java.util.regex.Pattern;


public class RegexSearchQuerySpec implements SearchQuerySpec
{

private static final byte CACHE_TYPE_ID = 0x3;

private final String pattern;
private final Pattern compiled;

@JsonCreator
public RegexSearchQuerySpec(
@JsonProperty("pattern") String pattern
)
{
this.pattern = Preconditions.checkNotNull(pattern, "pattern should not be null");
compiled = Pattern.compile(pattern);
}

@JsonProperty
public String getPattern()
{
return pattern;
}

@Override
public boolean equals(Object o)
{
if (this == o) {
return true;
}
if (!(o instanceof RegexSearchQuerySpec)) {
return false;
}

RegexSearchQuerySpec that = (RegexSearchQuerySpec) o;

return pattern.equals(that.pattern);

}

@Override
public int hashCode()
{
return pattern.hashCode();
}

@Override
public boolean accept(String dimVal)
{
if (dimVal == null) {
return false;
}

return compiled.matcher(dimVal).find();
}

@Override
public byte[] getCacheKey()
{
byte[] patternBytes = StringUtils.toUtf8(pattern);

return ByteBuffer.allocate(1 + patternBytes.length)
.put(CACHE_TYPE_ID)
.put(patternBytes)
.array();
}

@Override
public String toString()
{
return "RegexSearchQuerySpec{" +
"pattern=" + pattern + "}";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
@JsonSubTypes(value = {
@JsonSubTypes.Type(name = "contains", value = ContainsSearchQuerySpec.class),
@JsonSubTypes.Type(name = "insensitive_contains", value = InsensitiveContainsSearchQuerySpec.class),
@JsonSubTypes.Type(name = "fragment", value = FragmentSearchQuerySpec.class)
@JsonSubTypes.Type(name = "fragment", value = FragmentSearchQuerySpec.class),
@JsonSubTypes.Type(name = "regex", value = RegexSearchQuerySpec.class)
})
public interface SearchQuerySpec
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Licensed to Metamarkets Group Inc. (Metamarkets) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Metamarkets licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package io.druid.query.search;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.druid.jackson.DefaultObjectMapper;
import io.druid.query.search.search.RegexSearchQuerySpec;
import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;

public class RegexSearchQueryTest
{
private static final ObjectMapper jsonMapper = new DefaultObjectMapper();

@Test
public void testQuerySerialization() throws IOException
{
RegexSearchQuerySpec spec = new RegexSearchQuerySpec("(upfront|total_market)");

String json = jsonMapper.writeValueAsString(spec);
RegexSearchQuerySpec serdeQuery = (RegexSearchQuerySpec) jsonMapper.readValue(json, RegexSearchQuerySpec.class);

Assert.assertEquals(spec, serdeQuery);
}

@Test
public void testRegexCompare()
{
RegexSearchQuerySpec rsq = new RegexSearchQuerySpec("^a.*b");
Assert.assertTrue(rsq.accept("aabb"));
Assert.assertFalse(rsq.accept("babba"));
}
}

0 comments on commit 0eab841

Please sign in to comment.