# Proximity and "OR" or equivalency searching

**URL:** <https://discuss.elastic.co/t/proximity-and-or-or-equivalency-searching/27837>\
**Category:** Elasticsearch\
**Created:** [August 21, 2015, 2:46pm UTC](https://discuss.elastic.co/t/proximity-and-or-or-equivalency-searching/27837 "2015-08-21T14:46:50Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![ronchalant](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ronchalant/32/3611_2.png) [@ronchalant](https://discuss.elastic.co/u/ronchalant)\
**Post date:** [August 21, 2015, 2:46pm UTC](https://discuss.elastic.co/t/proximity-and-or-or-equivalency-searching/27837/1 "2015-08-21T14:46:50Z")

</div>

We're migrating from Oracle's text search using CONTAINS to Elastic, and one search commonly performed by our "power users" is a NEAR (proximity) search in conjunction with an EQUIValence (=) operator.

Equivalence operators basically allows users to define "synonyms" at runtime, which acts sort of like an 'OR' but allows the whole expression to be treated as a single term. So something like:

```
apple=orange=fruit

```

Would match on all three terms _equally_.

By itself it's not much more than an OR, but within a proximity (NEAR) search in Oracle you can do things like:

```
NEAR((apple=orange=fruit, smoothie=shake=milkshake), 3)

```

and the above would do a proximity search where the terms apple, orange OR fruit appear within a span of three terms of smoothie, shake or milkshake.

So far, if I use query string query syntax, the only way I could see to search the above would be something like:

```
"apple smoothie"~3 "orange smoothie"~3 "fruit smoothie"~3 "apple shake"~3 ... etc.

```

If we employed a synonym token filter for the above I assume (?) it could work the same, but is there any way this can be done at runtime? if not, perhaps it's something worthwhile to add?

---

<div class="post-metadata">

**Author:** ![polyfractal](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/polyfractal/32/48162_2.png) [@polyfractal](https://discuss.elastic.co/u/polyfractal)\
**Post date:** [August 21, 2015, 3:20pm UTC](https://discuss.elastic.co/t/proximity-and-or-or-equivalency-searching/27837/2 "2015-08-21T15:20:20Z")

</div>

> [@ronchalant](#):
>
> If we employed a synonym token filter for the above I assume (?) it could work the same, but is there any way this can be done at runtime? if not, perhaps it's something worthwhile to add?

Yep! You can index your data using one analyzer, then search it using a different analyzer. One of the best use-cases for that functionality is synonyms because most people don't want to actually index the synonyms, just match them at query time.

[Here is a quick demo I whipped up.](https://gist.github.com/polyfractal/1a6d61a56a0267fb5651) Basically you create an index with a synonym analyzer, index docs regularly, then use a match-phrase query with slop of 3 and the new `synonym` analyzer.

---

<div class="post-metadata">

**Author:** ![jpountz](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jpountz/32/45836_2.png) [@jpountz](https://discuss.elastic.co/u/jpountz)\
**Post date:** [August 21, 2015, 3:21pm UTC](https://discuss.elastic.co/t/proximity-and-or-or-equivalency-searching/27837/3 "2015-08-21T15:21:11Z")

</div>

I don't think you can solve this issue with the query\_string syntax. You would have to use the query dsl and the [span\_or](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-or-query.html) and [span\_near](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-near-query.html) queries.

---

<div class="post-metadata">

**Author:** ![ronchalant](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ronchalant/32/3611_2.png) [@ronchalant](https://discuss.elastic.co/u/ronchalant)\
**Post date:** [August 21, 2015, 3:22pm UTC](https://discuss.elastic.co/t/proximity-and-or-or-equivalency-searching/27837/4 "2015-08-21T15:22:39Z")

</div>

> [@polyfractal](#):
>
> Here is a quick demo I whipped up. Basically you create an index with a synonym analyzer, index docs regularly, then use a match-phrase query with slop of 3 and the new synonym analyzer.

awesome thanks man! I'll check it out

---

<div class="post-metadata">

**Author:** ![polyfractal](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/polyfractal/32/48162_2.png) [@polyfractal](https://discuss.elastic.co/u/polyfractal)\
**Post date:** [August 21, 2015, 3:25pm UTC](https://discuss.elastic.co/t/proximity-and-or-or-equivalency-searching/27837/5 "2015-08-21T15:25:07Z")

</div>

Ah, @jpountz brings up a good point I forgot about: phrase matching with slop doesn't guarantee ordering. So "smoothie fruit" is just as likely to match as "fruit smoothie", since phrase matching just checks for number of edits.

If you need order-dependent, sloppy phrase matching (eg. "fruit" must come before "smoothie") you'll probably need the span family like he mentioned. Or you could index 3-word shingles and search those instead.

---

<div class="post-metadata">

**Author:** ![ronchalant](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ronchalant/32/3611_2.png) [@ronchalant](https://discuss.elastic.co/u/ronchalant)\
**Post date:** [August 21, 2015, 3:29pm UTC](https://discuss.elastic.co/t/proximity-and-or-or-equivalency-searching/27837/6 "2015-08-21T15:29:57Z")

</div>

Order generally doesn't matter for our purposes, and we've got a 1-3 shingle setup for some of the relevant fields.

Part of this is getting our users to use the system more appropriately. I think our power-users will find that there are better ways to actually get at the data they want. The NEAR + EQUIV searches they've been doing with the Oracle search is, IMHO, more of a workaround of the limitations of the indexing therein.

Either way this is informative, thanks all!

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 5, 2017, 11:54pm UTC](https://discuss.elastic.co/t/proximity-and-or-or-equivalency-searching/27837/7 "2017-07-05T23:54:33Z")

</div>

Closed on July 5, 2017, 11:54pm UTC


