I want to query Elasticsearch using the "URI Search" format (https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html#search-uri-request) with a regex but cannot find out how to deal with regex special characters symbols like \s and the simple space.
Let's say I have the term [ apple computer ] stored in my index (keyword analyzer used).
the term will be found with :
curl -XGET http://es:9200/myindex/mytype/_search?q=name:/.*comp.*/&pretty
curl -XGET http://es:9200/myindex/mytype/_search?q=name:/.*appl.*/&pretty
curl -XGET http://es:9200/myindex/mytype/_search?q=name:/.*pple.*/&pretty
but what syntax should I use (in curl, or with another tool) to query using these regex :
/.*pple\s+compu.*/
/.*le +compu.*/
I think I've found the asnwer to my question:
First with my index setting being like this, I need to use name.keyword for a full text search
{
"myindex" : {
"aliases" : { },
"mappings" : {
"mytype" : {
"properties" : {
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
...
Then, doing a query using the "URI Search" format I have to use the tipycal conversion
a space should be written as +
+ should be written as %2b
anyother special characters in a url should be written with its %ASCII equivalent
so it turns out my regular expression /.*le +compu.*/ must be queried like that :
curl -XGET "http://es:9200/myindex/mytype/_search?q=name.keyword:/.*pple+%2bcomp.*/&pretty"
Finally, I can't see in the regexp doc or lucene any mention of the \s symbol as a wildcard for space, but not a big deal as it can be rewritten using regexp sub-patterns.
I have a file which has following data. I just want the ownerId numbers and the profileID values separated by :.
My file:
ObjectId("57a046a06f858a9c73b3468a"), "ownerId" : "923003345778", "profileId" : "FreeBundles,LBCNorthParentOffer", "instanceId" : null, "queuedFor" : "unassigned", "state" : "active", "createDateTime" : 1470121632, "startDateTime" : 1470121632, "expireDateTime" : 1485673632, "removeDateTime" : 1487747232, "extensionDateTime" : null, "cancelled" : false, "mode" : "onceOff", "nextMode" : "none", "profileData" : { "serviceProfileId" : "ecs19", "counter" : 1 } }
ObjectId("57a046a06f858a9c73b34688"), "cancelled" : false, "createDateTime" : 1470121632, "expireDateTime" : 1557514799, "extensionDateTime" : null, "instanceId" : null, "mode" : "onceOff", "nextMode" : "none", "ownerId" : "923003345778", "profileData" : { "serviceProfileId" : "ecs19", "counter" : 1 }, "profileId" : "Prov3G,HLRProv", "queuedFor" : "unassigned", "removeDateTime" : 1557514799, "startDateTime" : 1470121632, "state" : "active" }
ObjectId("56d48bd38a8b93baa708fcfa"), "ownerId" : "923003309452", "profileId" : "DiscountOnUsage,Segment04", "instanceId" : null, "queuedFor" : "unassigned", "state" : "active", "createDateTime" : 1456770003, "startDateTime" : 1456770003, "expireDateTime" : null, "removeDateTime" : null, "extensionDateTime" : null, "cancelled" : false, "mode" : "onceOff", "nextMode" : "none", "profileData" : { "serviceProfileId" : "ecs19", "counter" : 1 } }
ObjectId("560ed95f6ca6e0703cf26fcc"), "cancelled" : false, "createDateTime" : 1443813727, "expireDateTime" : 1544381999, "extensionDateTime" : null, "instanceId" : null, "mode" : "onceOff", "nextMode" : "none", "ownerId" : "923003309452", "profileData" : { "serviceProfileId" : "ecs19", "counter" : 1 }, "profileId" : "Prov3G,HLRProv", "queuedFor" : "unassigned", "removeDateTime" : 1544381999, "startDateTime" : 1443813727, "state" : "active" }
Output:
923003345778 : FreeBundles,LBCNorthParentOffer
923003345778 : Prov3G,HLRProv
923003309452 : DiscountOnUsage,Segment04
923003309452 : Prov3G,HLRProv
Please also explain me in detail the answer if anyone knows.
$ sed 's/.*ObjectId("\([^"]*\).*"profileId" *: *"\([^"]*\).*/\1 : \2/' file
57a046a06f858a9c73b3468a : FreeBundles,LBCNorthParentOffer
57a046a06f858a9c73b34688 : Prov3G,HLRProv
56d48bd38a8b93baa708fcfa : DiscountOnUsage,Segment04
560ed95f6ca6e0703cf26fcc : Prov3G,HLRProv
I really don't think any explanation is needed as it's very straight forward but let me know if you have any questions.
This is a rather awkward situation you've managed to put yourself into.
As a rule, you do not want to handle structured data with plain-text tools like sed. Any solution you come up with will be brittle in the face of formatting changes (such as spaces or newlines between JSON fields), and certain corner cases (such as JSON strings with quotation marks in them) are awkward to handle with it. If you have JSON, you want to use a JSON tool to handle it.
However, you don't exactly have JSON there. This is a textual representation of BSON (likely from MongoDB) that has already had some parts chopped off.
What you really want to do
A sane way to solve this problem is to make MongoDB give you JSON and let something like jq do the formatting. Once you have a proper JSON file, this will be as simple as
jq -r '"\(.ownerId) : \(.profileId)"' file.json
mongoexport may be your friend here, or putting JSON.stringify() around your query in the MongoDB shell1; it depends on how you got this data in the first place. This approach will require you to save the unchopped data, but anyway I suspect that whatever made you chop the BSON into pieces should be replaced with something similar to improve reliability.
1If you got the data from the MongoDB shell, you may want to consider doing the formatting there, though.
How to hack yourself deeper into this mess with sed
However, since you don't currently have proper JSON, you may want to try to hack yourself out of this mess with sed. This is a terrible idea, and I cannot stress enough that you never ever want to do this in a production environment. If you do, you'll be in a deeper mess than before, and that sort of vicious cycle is not a happy place to be.
So, what I'm about to show you is the sort of thing that you do as a one-off in a hurry and are never going to use again because you promise yourself to do it properly next time. You want to check the results carefully. Here goes:
sed 'h;/^.*"profileId"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/!d;s//\1/;x;/^.*"ownerId"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/!d;s//\1/;G;s/\n/ : /' file.bsonish
This makes the following assumptions about the input data:
One full object per line. Newlines in the wrong place will break this.
No " in either the ownerId or the profileID field
Furthermore, it will not recognize broken data, which is always a nice feature. On the upside, it does not require the ownerId and profileId fields to appear in any particular order.
It works as follows:
# Save a copy of the input data; we'll isolate the fields separately.
h
# See if there's a profileId field. If not, the line is silently dropped.
/^.*"profileId"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/!d
# Isolate that profileId field. // in this context means: reuse the last
# regex (the big one)
s//\1/
# Now swap in the saved input data. We'll get ownerId next.
x
# Isolate ownerId as before. If there is no ownerId field, drop line silently.
/^.*"ownerId"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/!d
s//\1/
# append profileId field in hold buffer to what we have
G
# Replace the newline between the two with a colon and some spaces.
s/\n/ : /
In my sandbox I have a collection, and the unique key (_id) for the collection is a unique string from another database. I have preallocated the documents and they look like this
The data looks like this
{ _id : "UNIQUEKEY1:1463670000000", data: {value:NaN} }
{ _id : "UNIQUEKEY2:1463670000000", data: {value:NaN} }
I would like to query the data in the following way
{ "_id": {$regex : "/^UNIQUEKEY1.*/i"} }
I have read that you can query _id if it is a string in Brendan's comment here
I don't want the overhead of another attribute just to search by when the _id would provide me with enough
It's a valid setup and $regex should work fine (see https://docs.mongodb.com/manual/reference/operator/query/regex/)
So try db.mycollection.find({ "_id": {$regex : /^UNIQUEKEY1.*/i} }) i.e. you shouldn't need the quote marks.
How to use nin and regex in mongoDB?
I want to find document using nin and regex
but nin does not work!
Query:
{ "$and" : [
{ "id" : { "$nin" : [ "529653cb5bc5b0e42d339bd3" , "529653cb5bc5b0e498339bd3"]}} ,
{ "content" : { "$regex" : "(?i)apple" , "$options" : "i"} }
] }
Should I using mongo subquery?
Your problem could be multiple things depending upon the error you're getting.
But a quick examination of your query suggests it could be your use of the "id" field. The primary key field in all documents is "_id". Your query uses the field "id" but you're probably trying to query the field "_id".
I use MongoDB. I create a database(500 000 000 documents) and collection in it for testing reasons. All documents look like bellow:
{
"_id" : ObjectId("50c1fbcda8cf8e11c43ea8ce"),
"sql_id" : 8311,
"text" : "WD7TYIM0H H3Q 3874 000 VFBF6H",
"xml" : "<root> <tag_0>WD7TYIM0H</tag_0> <tag_1>H3Q</tag_1> <tag_2>3874</tag_2><tag_3>000</tag_3><tag_4>VFBF6H</tag_4></root>",
"tags" : [
"WD7TYIM0H",
"H3Q",
"3874",
"000",
"VFBF6H"
]
}
I create index by field "tags" and want to use multiple regexp condition that uses "tags" index. Is this possible?
I tried:
> db.items.find({ "$and" : [{ "tags" : /^AAA/ }, { "tags" : /^BBB/ }] })
> db.items.find({ "tags" : { "$all" : [/^AAA/, /^BBB/] } })
twice Mongo went down.
If I search by one condition result returns very fast.
Thanks!
In my test it goes well. I'm using db version v1.6.5. Given the fact that I have only a few documents in DB, the problem may be a performance-related one.