How to use .indexOn for dynamic keys in firebase? - json

I have a DB in Firebase with this structure:
{
"chats" : {
"-L-hPbTK51XFwjNPjz3X" : {
"lastMessage" : "Hello!",
"timestamp" : 1512590440336,
"title" : "chat 1",
"users" : {
"Ol0XhKBksFcrYmF4MzS3vbODvT83" : true
}
}
},
"messages" : {
"-L-hPbTK51XFwjNPjz3X" : {
"-L-szWDIKX2SQl4YZFw9" : {
"message" : "Hello!",
"timestamp" : 1512784663447,
"userId" : "Ol0XhKBksFcrYmF4MzS3vbODvT83"
}
}
},
"users" : {
"Ol0XhKBksFcrYmF4MzS3vbODvT83" : {
"chats" : {
"-L-hPbTK51XFwjNPjz3X" : true
},
"email" : "mm#gmail.com",
"name" : "mm"
}
}
}
My code:
Database.database().reference().child("chats")
.queryOrdered(‌​byChild: "users/(userId)").queryEqual(toValue: true).observe(.value, with: { snapshot in .... }
When I try to get chat members or user chats, It shows this warnings:
Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding ".indexOn": "chats/-L-hPbTK51XFwjNPjz3X" at /users to your security rules for better performance.
Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding ".indexOn": "users/Ol0XhKBksFcrYmF4MzS3vbODvT83" at /chats to your security rules for better performance.
I found lots of solutions but anything works fine for me. I want to define IndexOn rules in my DB, Can you help me?

Related

How to acess an entity under _links in Angular from Spring Data REST?

I encountered a problem which is very challenging to my Angular level. Could you give a help please?
In Spring Data REST the entity Worker has a #OneToMany bidirectional relationship with the entity TempworkEvent, shown below under _links. I would like to access TempworkEvent objects and their attributes through this relationship.
{
"id" : 3,
"name" : "Nadja Miller",
"profession" : "Experte/in Anästhesiepflege",
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/workers/3"
},
"worker" : {
"href" : "http://localhost:8080/api/workers/3"
},
"tempworks" : {
"href" : "http://localhost:8080/api/workers/3/tempworks"
},
"tempworkEvents" : {
"href" : "http://localhost:8080/api/workers/3/tempworkEvents"
}
}
In Angular the Worker entity successfully:
getWorkers(): Observable<Worker[]> {
return this.httpClient.get<GetResponseWorkers>(this.workersUrl).pipe(
map(response => response._embedded.workers)
);
}
(...)
interface GetResponseWorkers {
_embedded: {
workers: Worker[];
}
}
The challenge is how to access the Worker's tempworkEvents object and its attributes through _links:
"tempworkEvents" : {
"href" : "http://localhost:8080/api/workers/3/tempworkEvents"
}
One of:
Make an additional network request to get the TempworkEvents
Don't have a TempworkEvent JPA repository, and Spring Data Rest will include the tempworkEvents data in the workers response
or, use a Projection, like:
in entities/projections/MyWorkerProjection.java:
#Projection(name="foo", types={Worker.class})
public interface MyWorkerProjection {
Long getId();
String getName();
String getProfession();
List<TempworkEvent> getTempworkEvents();
}
Then call http://localhost:8080/api/workers/3?projection=foo
If you want to have "auto" projections, see: Spring Data REST: projection representation of single resource
You may want to create another interface for TempworkEvent, if you want to project its data as well as its links
let obj = {
"id" : 3,
"name" : "Nadja Miller",
"profession" : "Experte/in Anästhesiepflege",
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/workers/3"
},
"worker" : {
"href" : "http://localhost:8080/api/workers/3"
},
"tempworks" : {
"href" : "http://localhost:8080/api/workers/3/tempworks"
},
"tempworkEvents" : {
"href" : "http://localhost:8080/api/workers/3/tempworkEvents"
}
}
}
console.log('tempworkEvents',obj._links.tempworkEvents);
You can access the object like above.

JSON Path - How to find the root elements based on child elements?

I have a JSON object, and I'm trying to find the root elements under it. Can someone please help me to figure this out?
{
"store" : {
"10162021" : {
"id" : 812340,
"properties" : {
"server" : "server1.example.org",
"serverip" : "",
}
},
"10162022" : {
"properties" : {
"serverip" : "127.0.0.1",
"server" : "server2.example.org",
},
"id" : 859480
}
}
}
I need to extract the root elements 10162022, 10162021 based on the server name.
I have tried to use syntax like below, but it was not successful
$..*..[?(#.server == server2.example.org)]
I will appreciate any suggestions.
It's not clear whether you want to return the keys "10162022", etc, or the values, like:
{
"properties" : {
"serverip" : "127.0.0.1",
"server" : "server2.example.org"
},
"id" : 859480
}
If you want to return values, the following JSONPath should work:
$.store[?( #.properties.server=="server2.example.org" )]
If you want to return keys, I'm not entirely sure that's possible. JSONPath isn't really designed to find keys, but values.
If you need the keys, I would suggest pre-processing the structure to stash the keys into objects as values, like this:
{
"store" : {
"10162021" : {
"__key" : "10162021",
"id" : 812340,
"properties" : {
"server" : "server1.example.org",
"serverip" : ""
}
},
"10162022" : {
"__key" : "10162022",
"properties" : {
"serverip" : "127.0.0.1",
"server" : "server2.example.org"
},
"id" : 859480
}
}
}
Then use this JSONPath:
$.store[?( #.properties.server=="server2.example.org" )].__key

MongoDB full text search inside embedded object

This is my sample data
{
_id: 123123123,
author:{
name : "username"
},
data:{
title : "Hello World"
}
}
And this is my Index command : db.post.createIndex({"data.title":"text"})
But when I execute db.post.find( { $text: { $search: "Hello" } } ) I get nothing back.
What command should I run to index an embed object inside mongodb?
This: db.post.createIndex({"data.title":"text"}) is the correct command to create a text index on an embedded field.
This: db.post.find( { $text: { $search: "Hello" } } ) is the correct way of engaging the text index to search for the value Hello in the embedded field: data.title.
You are doing everything correctly. To verify this, I have taken your document, written it to a collection, created a text index on that collection using the createIndex() command you supplied and searched for it using the find() command you supplied and that document is returned.
So, perhaps the issue is elsewhere. I would suggest that you:
Confirm that the text index was definitely created. You can do this by running db.post.getIndexes(), if the text index is present and does cover data.title then you should see something like this in the output from that command:
{
"v" : 2,
"key" : {
"_fts" : "text",
"_ftsx" : 1
},
"name" : "data.title_text",
"ns" : "<your database name>.post",
"weights" : {
"data.title" : 1
},
"default_language" : "english",
"language_override" : "language",
"textIndexVersion" : 3
}
Confirm that there is definitely a document with data.title containing Hello. You can do this by running a simple find: db.post.find({'data.title': { $regex: /Hello/ } }).
Confirm that this command: db.post.find( { $text: { $search: "Hello" } } ) definitely uses your text index. You can do this by invoking that command with .explain() (e.g. db.post.find( { $text: { $search: "Hello" } } ).explain()) and the output should include something like this:
"inputStage" : {
"stage" : "TEXT_MATCH",
"inputStage" : {
"stage" : "TEXT_OR",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"_fts" : "text",
"_ftsx" : 1
},
"indexName" : "data.title_text",
"isMultiKey" : true,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {}
}
}

Elasticsearch update mapping using json

I want to change the type of a field from 'string' to 'date' (format: 'epoch_second' to be specific). Since there is no way to update the mappings of an existing index, I need to make a new index for which I mostly want to use the mapping from my existing index. Here is what I am using:
curl -XGET 'http://localhost:9200/sam/saga/_mapping?pretty' >saga.json
to dump the mapping of the current index into a json file, the content of which is this:
{
"sam" : {
"mappings" : {
"saga" : {
"properties" : {
"name" : {
"type" : "long"
}
}
}
}
}
}
then I replace
"name" : {
"type" : "long"
}
with
"name" : {
"type" : "date"
}
and save the new file as saga2.json. then run this
curl -XPUT 'http://localhost:9200/sam/_mapping/saga2' -d #saga2.json
However, when I check the mapping of the new index, all types have changed to "string" now.
I even have this problem using the Elasticsearch's example.
Does anyone know what is wrong?
You need to make one more change in your saga2.json file, namely the mapping type name saga -> saga2 (Now you probably need to rename it all to saga3
{
"sam" : {
"mappings" : {
"saga2" : { <--- here
"properties" : {
"name" : {
"type" : "date" <--- and here
}
}
}
}
}
}
Then only you can run this:
curl -XPUT 'http://localhost:9200/sam/_mapping/saga2' -d #saga2.json

How to create an index with integer fields in Elasticsearch for the JSON file of format?

I am trying to create an index in Elasticsearch for the JSON file of format:
{ "index" : { "_index" : "entity", "_type" : "type1", "_id" : "0" } }
{ "eid":"guid of Event autogenerated", "entityInfo": { "entityType":"qualityevent", "defaultLocale":"en-US" }, "systemInfo": { "tenantId":"67" }, "attributesInfo" : { "jobId":"21", "matchStatus": "new" } }
{ "index" : { "_index" : "entity", "_type" : "type1", "_id" : "1" } }
{ "eid":"guid of Event autogenerated", "entityInfo": { "entityType":"qualityevent", "defaultLocale":"en-US" }, "systemInfo": { "tenantId":"67" }, "attributesInfo" : { "jobId":"20", "matchStatus": "existing" } }
I want the fields jobId and tenantId to be integers.
I am giving the following mapping in curl command:
curl -XPUT http://localhost:9200/entity -d '
{
"mappings": {
"entityInfo":
{
"properties" : {
"entityType" : { "type":"string","index" : "not_analyzed"},
"defaultLocale":{ "type":"string","index" : "not_analyzed"}
}
},
"systemInfo":
{
"properties" : {
"tenantId": { "type" : "integer" }
}
},
"attributesInfo" :
{
"properties" : {
"jobId": { "type" : "integer" },
"matchStatus": { "type":"string","index" : "not_analyzed"}
}
}
}
}
';
This does not give me an error. However, it creates new empty fields jobId and tenantId as integers and it keeps the existing data into attributesInfo.jobId as string. Same is the case with systemInfo.tenantId. I want to use these two fields in Kibana for visualization. I currently cannot use them as they are empty.
I am new to Kibana and Elasticsearch so I am not sure if the mapping is correct.
I have tried couple of other mappings as well but they give errors. Above mapping does not give error.
This is how Discover Tab on Kibana looks like: 1
Please let me know where I am going wrong.
I tried as you mentioned but it didn't help. What I realised after a lot of trial and error that my mapping was incorrect. I finally wrote the correct mapping and now it works correctly. Jobid and TenantId are recognised as numbers by Kibana. I am new to JSON, kibana, Bulk, Elastic so it took time to understand how mapping works.