Arangodb dynamic index on object keys - indexing

Arangodb 2.8b3
Have document with some property "specification", can have 1-100 keys inside, like
document {
...
specification: {
key1: "value",
...
key10: "value"
}
}
Task fast query by specification.key
For Doc IN MyCollection FILTER Doc.specification['key1'] == "value" RETURN Doc
Tried create hash indexes with field: "specification", "specification.*", specification[*], specification[*].*
Index never used, any solution without reorganizing structure or plans for future exists?

No, we currently don't have any smart idea how to handle indices for structures like that. The memory usage would also increase since the attribute names would also have to be present in the index for each indexed value.
What we will release with 2.8 is the ability to use indices on array structures:
db.posts.ensureIndex({ type: "hash", fields: [ "tags[*]" ] });
with documents like:
{ tags: [ "foobar", "bar", "anotherTag" ] }
Using AQL queries like this:
FOR doc IN posts
FILTER 'foobar' IN doc.tags[*]
RETURN doc
You could also index documents under arrays:
db.posts.ensureIndex({ type: "hash", fields: [ "tags[*].value" ] });
db.posts.insert({
tags: [ { key: "key1", value: "foobar"},
{ key: "key2", value: "baz" },
{ key: "key3", value: "quux" }
] });
The following query will then use the array index:
FOR doc IN posts
FILTER 'foobar' IN doc.tags[*].value
RETURN doc
However, the asterisk can only be used for array accesses - it can't substitute key matches in objects.

Related

Replace Objects with the corresponding ObjectId with Mongoose if found in the MongoDB

I have a MEAN-Stack setup in which i have Devices and Servicecases saved in the MongoDB-Database.
Devices can be the content of a Servicecase
If a new Case should be created, my Frontend will deliver the following form data:
content: [
{
"device": 012345678909876,
"errorDesc": "lorem"
},
{
"device": 012345678909876,
"errorDesc": "ipsum"
}
]
There could be a device document with the submitted device number in the Database. If yes, the received doc should be populated with its ObjectId to look like this:
content: [
{
device: { type: Schema.Types.ObjectId, ref: 'Device' },
errorDesc: String
},
...
]
If not, it should stay as it is
I could iterate through each device of the array and use the findOne() query and, if a doc was found, replace it, but is there a more efficient way to use the populate() transformation?

Is there a way to sort documents by an integer using faunaDB?

Is there a way to sort documents by an integer with indexes using faunaDB? I have multiple documents with data.likes, which is an integer. Is it possible to simply get the documents by most likes sorted first, and the least sorted last? Thanks in advance
Yes.
To do this, make sure that your index includes the likes field in the values definition. If you specify reverse: true for that field, you'll see the results sorted in descending order.
For example:
CreateIndex({
name: 'popular-pets',
source: Collection('pets'),
values: [
{ field: ["data", "likes"], reverse: true },
{ field: ["ref"] },
],
})
Then you can do this:
Map(
Paginate(Match(Index("popular-pets"))),
Lambda(["likes", "ref"], Get(Var("ref")))
)

Creating an index for all active items

I have a collection of documents that follow this schema {label: String, status: Number}.
I want to introduce a new field, deleted_at: Date that will hold information if a document has already been deleted. Seems like a perfect use case for an index, to be able to search for all undeleted tasks.
CreateIndex({
name: "activeTasks",
source: Collection("tasks"),
terms: [
{ field: ["data", "deleted_at"] }
]
})
And then filter by undefined / null value in shell:
Paginate(Match(Index("activeTasks"), null))
Paginate(Match(Index("activeTasks"), undefined))
It returns nothing, even for documents where I explicitly set deleted_at to null.
That's not my point, though. I want to get documents that do not have the deleted_at defined at all, so that I do not have to update the whole collection.
PS. When I add document where deleted: "test" and query for it, the shell does return the expected result.
What do I don't get?
The reason is because FaunaDB doesn't support reading empty/null value the way you think it does. You need to use a special Bindings to do that.
Make sure to check out https://docs.fauna.com/fauna/current/tutorials/indexes/bindings.html#empty for a more thorough explanation and examples.
My understanding of how bindings work would yield the following code. I haven't tested it though and I'm not sure it works.
You need a special binding index:
CreateIndex({
name: "activeTasks",
source: [{
collection: Collection("tasks"),
fields: {
null_deleted_at: Query(
Lambda(
"doc",
Equals(Select(["data", "deleted_at"], Var("doc"), null), null)
)
)
}
}],
terms: [ {binding: "null_deleted_at"} ],
})
Usage:
Map(
Paginate(Match(Index("activeTasks"), true)),
Lambda("X", Get(Var("X")))
)

Is there a way to Index a doc to Elasticsearch with a specific _id filed?

I'm looking to simulate a state where I have a specific _id field inside an index.
Let's assume I want to take the EXACT same log from index1 in my example and index it into index2.
Like so:
This is my index1
{
_index: "index-number-one",
_type: "doc",
_id: "S0meSpec!f!cID",
_score: 1,
_source: {
message: "message1",
type: "type1",
tags: [
"_bla"],
number: 3
}
}
Now I want that exact same log in my index2
{
_index: "index-number-two",
_type: "doc",
_id: "S0meSpec!f!cID",
_score: 1,
_source: {
message: "message1",
type: "type1",
tags: [
"_bla"],
number: 3
}
}
Couldn't find an API in Elasticsearch that can insert a doc to an Index with a specific _id field... (?)
If this action isn't possible so that the Elasticsearch cluster won't have duplications in the _id field, I can imagine it's because they want to keep the ability to search a doc by it's _id
field which needs to be unique, in that case, assume that I don't mind deleting the entire doc from index1 (maybe save it aside as some variable in my code), but in the end, I need the doc in index2, to have the EXACT _id as index1 once had.
And if there's a way to edit an existing _id field it would also solve my problem.
Can anyone please shed any light on how to achieve that goal?
answer to myself,
I found that it can be done in a POST request on the index like so:
POST twitter/test-index-1234/abctype/Som3Cust0mID
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
And the outcome in ES:
{
_index: "test-index-1234",
_type: "abctype",
_id: "Som3Cust0mID",
_score: 1,
_source: {
user: "kimchy",
post_date: "2009-11-15T14:12:12",
message: "trying out Elasticsearch"
}
}
It is definitely possible to do this. IDs are unique per index, not per cluster.
Check the reindex API, it copies one index onto another and keeps the document IDs.
It is also possible to change the ID using a script inside the reindex call.

Cloudant search document by attributes of nested objects

My documents in cloudant have the following structure
{
"_id" : "1234",
"name" : "test",
"objects" : [
{
"type" : "TYPE1"
"time" : "1215
},
{
"type" : "TYPE2"
"time" : "1115"
}
]
}
Now I need to query my documents by a list of types.
Examples
1) If I would query with TYPE1 then all the documents where there is an object with this type would return. (The example doc would return)
2) If I would query with TYPE1 and TYPE3 it would return all documents which contain either of them (The example doc would return)
3) If I would query with TYPE3, TYPE4 and TYPE5 it would return all documents which contain either of them (The example doc would not return)
How would the code in the _design document look like and how would my API request look like?
One option is to use Cloudant Search.
Sample design document named types, which indexes each type property in your objects array
{
"_id": "_design/types",
"views": {},
"language": "javascript",
"indexes": {
"one-of": {
"analyzer": "standard",
"index": "function (doc) {\n for(var i in doc.objects) {\n index(\"type\", doc.objects[i].type); \n }\n}"
}
}
}
Query examples:
Search for one key (type=val)
GET https://$HOST/$DATABASE/_design/$DDOC/_search/one-of?q=type%3ATYPE1
Search for multiple keys (type=val1 OR type=val2)
GET https://$HOST/$DATABASE/_design/$DDOC/_search/one-of?q=type%3ATYPE1%20OR%20type%3ATYPE2
Search for multiple keys (type=val1 AND type=val2)
GET https://$HOST/$DATABASE/_design/$DDOC/_search/one-of?q=type%3ATYPE1%20AND%20type%3ATYPE2
To include the documents in the response append &include_docs=true.