appbaseio / reactivesearch

Search UI components for React and Vue
https://opensource.appbase.io/reactivesearch
Apache License 2.0
4.89k stars 471 forks source link

Feature: Add support for `nested` object mapping #595

Open siddharthlatest opened 5 years ago

siddharthlatest commented 5 years ago

Issue Type:

Enhancement

Platform:

ReactiveSearch for Web

Description:

ReactiveSearch today doesn't support querying the fields of an object field with a nested mapping.

A nested object requires a different query (where a path for the nested field needs to be specified) along with the original query. The same applies to an aggregation.

This issue proposes to add a nestedField prop in all the data-driven components we have to support the use-case of a nested object.

Prop definition for the field looks like:

nestedField String [optional]
When your dataField is present inside an object of type nested, this can be used to set the path of the nested field. Setting this allows searching within documents belonging to the path.

Reactivesearch version: x.y.z

2.12.1

Components to support this in:

aol-nnov commented 5 years ago

@metagrover here is my contrib for nested fields in MultiList. Should I make a PR?

https://github.com/aol-nnov/reactivesearch/commit/a797ba6097d3c9bcee8be5a5729d9d1caeb8cff9

metagrover commented 5 years ago

@aol-nnov Left the reviews on the commit. Thanks for taking out the time to work on this!

aol-nnov commented 5 years ago

Thanks, I'll revisit the changes soon.

It worked for me months before, but I was never confident if it's a clear fix for nested fields.

aol-nnov commented 5 years ago

@metagrover I've redone my changes in MultiList.

My previous idea was to store "nested" part of property name in nestedField i.e. vendor is nested object with field name

dataField: 'name'
nestedField: 'vendor'

(it was some time before your changes for nested mapping support)

Now, I've followed your guidelines and made it your way:

dataField: 'vendor.name'
nestedField: 'vendor'

tested it with my local ES instance of my project. Everyting works like a charm! Finally I do not need a patched reactivesearch, hooray! ;)

aol-nnov commented 5 years ago

~~@metagrover I've just noticed a weird thing: terms in MultiList are displayed fine, but if I tick one (or several) of them, results in the ResultCard are not filtered.

Any clue what I've missed? (It was working fine with my approach you reviewed yesterday)~~

Oh, please disregard this. It's me again. Everything is okay with this patch.

metagrover commented 5 years ago

Probably something's off with the defaultQuery. Check if the final query is being wrapped by nested query?

I'm looking into this!

aol-nnov commented 5 years ago

no need to.. It was me again ). I've updated the comment (strike through was not applied though)

TCMiranda commented 5 years ago

Hey guys, thanks for this, really helpful! Here follows an observation: One nested property is allowed to have another nested one inside it. This API doesn't support that case.

Since it is a new API, wouldn't it be appropriate to consider an API definition which enables this "recursion" into the appropriate nested level?

I believe its a corner case, but i've come to it recently:


{
  nested: {
    path: 'trajectory',
    query: {
      nested: {
        path: 'trajectory.company',
        query: {
          simple_query_string: {
            query: value,
            fields: ['trajectory.company.name'],
          },
        },
      },
    },
  },
}
MarttiR commented 4 years ago

@TCMiranda This is a must-have.

Consider such documents:

{
  nestedArrayField: [
    {
      nestedTranslatedField: {
        code: "some_string",
        en: "SomeString",
        fi: "JokinMerkkijono"
      }
    },
    {
      nestedTranslatedField: {
        code: "some_other_string",
        en: "SomeOtherString",
        fi: "JokinMuuMerkkijono"
      }
    }
  ]
}

Currently, it doesn't seem to be possible to use values from the nested translated field.

siddharthlatest commented 4 years ago

@MarttiR You can achieve this via customQuery prop, where you can pass the QueryDSL directly.

TCMiranda commented 4 years ago

@siddharthlatest I believe you can, but components are not prepared for that. They lack the option to map responses to internal features, like the dropdown options, the range histogram, etc.

Making it impossible to work with standard components just by using customQuery.

Disclosure: it has been some time since I worked with this library, so I'm not sure it is solved. At the time we faced this issue, we created a parser using a serviceWorker to translate a special syntax we defined to deal with "nested" nested fields.

flavienbwk commented 2 years ago

Still an issue. For example, if I have a nested field data and the following ReactiveSearch's DataSearch component configuration :

dataField={["data.*"]}
nestedField='data'

it doesn't find anything.

_I can't specify all fields in datafield such as [data.field_1, data.field_2] because there are dozens of it and they are random depending on the data I inject (auto mapping)._

RobinBrackez commented 1 year ago

I searched a long time to make this work. For anyone interested:

Use MultiList, not MultiDataList. It doesn't work on the latter.

Use it like this:

  <MultiList
    dataField="tags.name"
    nestedField="tags"

The query to elastic should look like this: {"query":{"match_all":{}},"size":0,"aggs":{"reactivesearch_nested":{"nested":{"path":"tags"},"aggs":{"tags":{"terms":{"field":"tags.name","size":20,"order":{"_key":"asc"}}}}}}}