Query document with embedded document field using spring data repository - spring

I am new to Spring-data, so pardon me if my question is to naive
I am trying to query the document which looks like this:
{
_id: 1,
name: "sue",
age: 19,
type: 1,
status: "P",
favorites: { artist: "Picasso", food: "pizza" },
finished: [ 17, 3 ],
badges: [ "blue", "black" ],
points: [
{ points: 85, bonus: 20 },
{ points: 85, bonus: 10 }
]
}
I wanted to do the query which gives me the list of the entries which contains the favourites.artist="Picasso".
I know how to do this using the MongoTemplate I wanted to do that using MongoRepository.
I was reading some document which shows query like this
findByFavorites(Favorites favorites)
but I couldn't find anything with which I can query using the field of the embedded document.

It should be
findByFavoritesArtist(#Param("favorites.artist") String artist);
So you just concatenate together the names of the properties in the property path in our embedded object. It is possible that the above query is redundant and you can leave out the #Param annotation.

Related

How to get distinct keys of a nested object in an elasticsearch document?

I'd like to look across an index for a unique list of keys in a nested object.
So in the example below, I want the output
["alpha", "beta", "gamma", "sigma", "theta" ]
Much of the google search results were around unique values instead of the keys.
Example docs:
{
"foo": "bar",
"fooNested": {
"alpha": 1,
"beta": 4,
"gamma": 2,
}
},
{
"foo": "HelloWorld",
"fooNested": {
"sigma": 9,
"theta": 1
}
}
Is this possible using the rest api?
You can use mapping api to get all properties in index and parse it client side to list properties under nested object or you can store fields as values and query it.
example.
"fooNested": {
"sigma": 9,
"theta": 1,
"keys":["sigma","theta"]
}

How to access celldata objects in sheets api

I'm working on a google sheets integration project where I'd like to add formatted text to cells (bold, italic). This needs to be for only part of the cell (e.g. only some of the text in the cell is bold ) I can see that this can be done though the CellData object, documented in the sheets api here:
CellData
But I can't work out how to get an instance of these objects. I'm using the sheets service to successfully get a SpreadSheet, Sheet and ValueRange objects, but I can't work out how to get through to the cell data objects themselves to use these methods.
When a part of value of a cell has several formats, you want to retrieve the formats.
You want to put a value with several formats to a cell.
I understand your question as above. If my understanding is correct, how about these samples?
1. Retrieve value
When a part of value of a cell has several formats like below image,
the script for retrieving the values with the formats is as follows.
Sample script:
This sample script retrieves the value from the cell "A1" of "Sheet1".
spreadsheet_id = '### spreadsheet ID ###'
ranges = ['Sheet1!A1']
fields = 'sheets(data(rowData(values(textFormatRuns,userEnteredValue))))'
response = service.get_spreadsheet(spreadsheet_id, ranges: ranges, fields: fields)
Result:
{
"sheets": [
{
"data": [
{
"rowData": [
{
"values": [
{
"userEnteredValue": {
"stringValue": "abcdefg"
},
"textFormatRuns": [
{
"format": {}
},
{
"format": {
"fontSize": 24,
"foregroundColor": {
"red": 1
},
"bold": true
},
"startIndex": 2
},
{
"format": {},
"startIndex": 5
}
]
}
]
}
]
}
]
}
]
}
2. Put value
When a value with several formats is put to a cell, the script is as follows.
Sample script:
This sample script puts the value to the cell "B1" of "Sheet1". As a sample, update_cells is used for this situation.
spreadsheet_id = '### spreadsheet ID ###'
requests = {requests: [
update_cells: {
fields: 'userEnteredValue,textFormatRuns',
range: {sheet_id: 0, start_row_index: 0, end_row_index: 1, start_column_index: 1, end_column_index: 2},
rows: [{values: [{user_entered_value: {
string_value: 'abcdefg'},
text_format_runs: [{format: {}}, {format: {font_size: 24, foreground_color: {red: 1}, bold: true}, start_index: 2}, {format:{}, start_index: 5}]
}]}]
}
]}
response = service.batch_update_spreadsheet(spreadsheet_id, requests, {})
About sheet_id: 0, if you want to other sheet, please modify it.
Result:
Note:
These sample scripts supposes that your environment can use Sheets API.
These are simple samples. So please modify them to your situation.
References:
spreadsheets.get
spreadsheets.batchUpdate
textFormatRuns
updateCells

Hiding _source fields based on other fields

Let's say I have two documents in a Elasticsearch index:
[
{
"foo": 1,
"bar": 2,
"visible_fields": ["foo"]
},
{
"foo": 1,
"bar": 2,
"visible_fields": ["bar"]
}
]
I want only the fields listed in visible_fields for each document to be returned in a query response. How would I do that?
I'm thinking a custom plugin or script could solve it but I don't know how or where to start. Looking through the source code for the existing plugins I can't find anything that I can use to access and modify the _source fields.

Elasticsearch & X-Pack: how to get vertices/connections from nested documents

I just started using X-Pack for Elasticsearch and want to connect vertices from a nested document type. However, looking for documentation on this hasn't got me anywhere.
What I have is an index of documents which have person names/ids as nested documents (one document can have many persons, one person can be related to many documents). The desired result is to get a graph data with connections between persons.
Does anyone have a clue or can tell me if this is even possible?
Part of my mappings:
mappings: {
legend: {
properties: {
persons: {
type: 'nested',
properties: {
id: {
type: 'string',
index: 'not_analyzed'
},
name: {
type: 'string',
index: 'not_analyzed'
}
}
}
}
}
}
And my Graph API query, which of course doesn't work because I don't know how to handle the "name" field of the nested "persons" field.
POST sagenkarta_v3/_xpack/_graph/_explore
{
"controls": {
"use_significance": true,
"sample_size": 20000,
"timeout": 2000
},
"vertices": [
{
"field": "persons.name"
}
],
"connections": {
"vertices": [
{
"field": "persons.name"
}
]
}
}
Thanks in advance!
The following question was discussed here:
https://discuss.elastic.co/t/elasticsearch-x-pack-how-to-get-vertices-connections-from-nested-documents/88709
quote from Mark_Harwood - Elastic Team Member:
Unfortunately Graph does not support nested documents but you can use
copy_to in your mappings to put the person data in an indexed field in
the containing root document.
I can see that you have the classic problem of
"computers-want-IDs-but-people-want-labels" and have both these
values. In Graph (and arguably the rest of Kibana too) I suggest you
use tokens that combine IDs for uniqueness' sake and names for
readability by humans.
The copy_to and IDs-and-labels tips are part of the modelling
suggestions in my elasticon talk this year:
https://www.elastic.co/elasticon/conf/2017/sf/getting-your-data-graph-ready
3

How to remove a key from a RethinkDB document?

I'm trying to remove a key from a RethinkDB document.
My approaches (which didn't work):
r.db('db').table('user').replace(function(row){delete row["key"]; return row})
Other approach:
r.db('db').table('user').update({key: null})
This one just sets row.key = null (which looks reasonable).
Examples tested on rethinkdb data explorer through web UI.
Here's the relevant example from the documentation on RethinkDB's website: http://rethinkdb.com/docs/cookbook/python/#removing-a-field-from-a-document
To remove a field from all documents in a table, you need to use replace to update the document to not include the desired field (using without):
r.db('db').table('user').replace(r.row.without('key'))
To remove the field from one specific document in the table:
r.db('db').table('user').get('id').replace(r.row.without('key'))
You can change the selection of documents to update by using any of the selectors in the API (http://rethinkdb.com/api/), e.g. db, table, get, get_all, between, filter.
You can use replace with without:
r.db('db').table('user').replace(r.row.without('key'))
You do not need to use replace to update the entire document.
Here is the relevant documentation: ReQL command: literal
Assume your user document looks like this:
{
"id": 1,
"name": "Alice",
"data": {
"age": 19,
"city": "Dallas",
"job": "Engineer"
}
}
And you want to remove age from the data property. Normally, update will just merge your new data with the old data. r.literal can be used to treat the data object as a single unit.
r.table('users').get(1).update({ data: r.literal({ age: 19, job: 'Engineer' }) }).run(conn, callback)
// Result passed to callback
{
"id": 1,
"name": "Alice",
"data": {
"age": 19,
"job": "Engineer"
}
}
or
r.table('users').get(1).update({ data: { city: r.literal() } }).run(conn, callback)
// Result passed to callback
{
"id": 1,
"name": "Alice",
"data": {
"age": 19,
"job": "Engineer"
}
}

Resources