I have a list of string values which used as a whitelist.
For example:
{
"whitelist": ["a", "b", "c"]
}
In Elastic Search I have many documents, each one contains an array of strings, like:
doc_1
{
"values": ["a", "y", "b"]
}
doc_2
{
"values": ["a", "c"]
}
I want to filter out all the documents that contain at least one value that is not contained in the whitelist.
In the example above, the requested result is doc_2, as it doesn't contain any value which is not in the whitelist, while doc_1 does contain value "y".
Is there any way to do such a thing without an external code outside of ElasticSearch?
Related
Think like you are implementing Like function of chat app.
You wanna store the information all people's name who liked a specific comment in db.
for memory reason, you don't wanna store the information which comments a specific person liked so far in db.
So what you wanna do is
# commend-id1: (user1, user2, user3)
# comment-id2: (user2]
# comment-id3: (user1)
# You wanna convert above into below by some codes
# user1: (comment-id1, comment-id3)
# user2: (comment-id2)
# user3: (comment-id1)
Is there any efficient way to achieve this?
EDIT::
someone commented the above example is impossible with efficient way.
how about this?
data = {
"field_a": {
"name": "index_a",
"used_fields": ["a", "b", "c"]
},
"field_b": {
"name": "index_b",
"used_fields": ["d", "b", "d"]
},
"field_c": {
"name": "index_c",
"used_fields": ["a"]
}
}
# you wanna convert above into below
# a. index_a, index_c
# b. index_a, index_b
# c. index_a
I have defined a sequence like so:
<#assign seq = ["A", "B", "C", "D", "E"]>
I can do: <#list seq[0..] as i>${i}</#list> which will generate an output of ABCDE
Is it possible to get the sequence back in the original format? I.e. ["A", "B", "C", "D", "E"]
For reference, I am using this to first assign an empty sequence and then elements items into it. I want to get the full sequence at the end in the original sequence format because it will be part of a JSON.
There's nothing specialized on that, but you can do this (not sure what escaping syntax you need though, so here I used JSON):
[<#list seq as it>"${it?json_string}"<#sep>, </#list>]
This will return back the original sequence format:
<#assign seq = ["A", "B", "C", "D", "E"]>
[<#list seq[0..] as i><#if i?has_next>"${i}",<#else>"${i}"</#if></#list>]
What would be the easiest way in Ruby to pop a specific element from an array, similar to the .delete method of
a.delete(element)
rather than popping the first/last element or using .slice?
To make this more specific: for example, I can do
case names.sample when "John", "Dave", "Sam"
a.delete(names.sample)
end
to delete one of those names from a when it appears as a sample from names
However, I intend to use multiple samples and using a.delete()will remove all elements at once, rather than in succession like the result produced from shuffle!.pop where elements are popped in succession, so that the name can no longer be selected as a sample from a after the same name has been selected as a name.sample
I was wondering what the easiest way would be in Ruby to pop off these elements in succession, or if it is even possible at all in this context.
The Array class defines a pop method. It returns and deletes the last element in the array.
a = ["a", "b", "c"]
puts a.pop #=> "c"
puts a #=> ["a", "b"]
You can optionally pass an argument to pop that specifies how many elements to pop off.
a = ["a", "b", "c"]
puts a.pop(2) #=> ["b", "c"]
puts a #=> ["a"]
Addressing your last comment, you can use include?, index, and delete_at methods to achieve this. Assuming you're checking for "b" in an array:
a = ["a", "b", "c"]
value_index = a.index("b") #Returns the first occurring index of "b"
has_value = a.include?("b") #Returns whether "b" is in the list
a.delete_at(a.index("b")) if has_value #Removes "b" from the list
In this sample, "has_value" will be whether the a array contains the value "b", and "value_index" will be the first occurrence of "b". This will also delete the value "b" from the list.
If you want to remove all occurrences of "b", you can use include?, index, and delete_at with a while loop:
a = ["a", "b", "c", "a", "b", "c"]
while a.include?("b")
a.delete_at(a.index("b"))
end
#a will now be ["a", "c", "a", "c"]
See also the documentation for Array.
[..] intend to use multiple samples and using a.delete() will remove all elements at once, rather than in succession like the result produced from shuffle!.pop where elements are popped in succession, so that the name can no longer be selected as a sample from a after the same name has been selected as a name.sample[..]
Maybe you are looking something like this?
names = ["John", "Dave", "Sam"]
names.size.times { p names.delete(names.sample) }
#=> "Sam"
#=> "John"
#=> "Dave"
I have a document structure as follows:
{
"documentId": 123,
"someOtherInfo": {...}
"permissions": ["a", "b, ..., "g"]
}
Users themselves have a permission set ["x", "y", "z"]. Business Rule: User A is allowed to view document X if and only if at least one of the user permissions matches documents permissions. Or put mathematically, if intersection is nonempty -
["a", "b, ..., "g"] ∩ ["x", "y", "z"] ≠ ∅
I am building a search engine that needs to find all documents user has access to. I want to store it in Elastic Search for all the great querying capabilities it provides, but how do I add a restriction for permissions using ES DSL? Many thanks.
You need a terms query where an array whose element is to be matched can be passed. This match documents containing any of the provided terms. As an example , the following will match the document containing permissions = ["a", "b", "c"] but not permissions = ["a", "t", "c"]
{
"query": {
"terms": {
"permissions": [
"x",
"y",
"z",
"b"
]
}
}
}
This is a add on for a question I asked yesterday but felt it warranted a new question.
I am taking a JSON response and want to extract all the values per iteration and put them into an array
#response = { "0"=>{"forename_1"=>"John", "surname_1"=>"Smith", forename_2"=>"Josephine", "surname_2"=>"Bradley", "middle_1"=>""},
"1"=>{"forename_1"=>"Chris", "surname_1"=>"Jenkins", forename_2"=>"Christine", "surname_2"=>"Sugar", "middle_1"=>""},
"2"=>{"forename_1"=>"Billy", "surname_1"=>"Bob", forename_2"=>"Brenda", "surname_2"=>"Goodyear", "middle_1"=>""},
"Status" => 100
}
At present this method takes specific values that I want and puts them into the array I want.
col = #response.values.grep(Hash).map { |h| "#{h['forename_1']} #{h['surname_1']} #{h['forename_2']} #{h['surname_2']} #{h['middle_1']}" }
Is there a way however to say grab ALL the values and place them into an array (I have a response where over 25 key/value pairs are returned).
At the moment if middle_1 has no value then a " " gets put into the array, ideally I would like to remove these.
Ideally I would like my newly formed array to look like
["John Smith Josephine Bradley", "Chris Jenkins Christine Sugar", "Billy Bob Brenda Goodyear"]
Even though no middle_1 is supplied there is are no double spaces in the array. I would like to learn how to tackle this.
Maybe will provide example of "cracking" the hash and extracting what you would need:
h = {a1: "a", b2: "b", c3: "", d4: nil, e5: "e"}
values = h.values.map(&:to_s).reject(&:empty?)
# => ["a", "b", "e"]
values.join(" ")
# => "a b e"
Let's consider the h.values.map(&:to_s).reject(&:empty?):
values = h.values
# => ["a", "b", "", nil, "e"]
values = values.map(&:to_s)
# => ["a", "b", "", "" "e"]
values = values.reject(&:empty?)
# => ["a", "b", "e"]
Hope that gives you some idea how you can proceed.
Good luck!
UPDATE
For provided hash you can quite easily reuse what I have described above like:
col = #response.values
.grep(Hash)
.map { |h| h.values.map(&:to_s).reject(&:empty?).join(" ") }
p col
# => ["John Smith Josephine Bradley", "Chris Jenkins Christine Sugar", "Billy Bob Brenda Goodyear"]