Да, \
в строковых литералах Python обозначает начало escape-последовательности. На вашем пути у вас есть действительная двухсимвольная escape-последовательность \a
, которая сжимается на символ one , который является ASCII Bell :
>>> '\a'
'\x07'
>>> len('\a')
1
>>> 'C:\meshes\as'
'C:\\meshes\x07s'
>>> print('C:\meshes\as')
C:\meshess
Другие общие escape-последовательности включают в себя \t
(вкладка), \n
(строка), \r
(возврат каретки):
>>> list('C:\test')
['C', ':', '\t', 'e', 's', 't']
>>> list('C:\nest')
['C', ':', '\n', 'e', 's', 't']
>>> list('C:\rest')
['C', ':', '\r', 'e', 's', 't']
Как вы можете видеть, во всех этих примерах обратная косая черта и следующий символ в литерале были сгруппированы вместе, чтобы сформировать единственный символ в финальной строке. Полный список управляющих последовательностей Python здесь здесь .
Существует множество способов борьбы с этим:
r
или R
: >>> r'C:\meshes\as'
'C:\\meshes\\as'
>>> print(r'C:\meshes\as')
C:\meshes\as
os.path.join
... >>> import os
>>> os.path.join('C:', os.sep, 'meshes', 'as')
'C:\\meshes\\as'
pathlib
модуль >>> from pathlib import Path
>>> Path('C:', '/', 'meshes', 'as')
WindowsPath('C:/meshes/as')
Кажется, вы думаете, что в конвейере агрегации можно вызвать функцию JavaScript, но вы не можете этого сделать. Вы ошибаетесь, что на самом деле является «интерполяцией» переменной из результата функции для выполнения внутри конвейера.
Например, если я это сделаю:
var getNumbers = function() { return [ 1,2,3 ] };
Затем я вызываю это :
db.collection.aggregate([
{ "$project": {
"mynums": getNumbers()
}}
])
Затем, что на самом деле происходит в оболочке JavaScript, значения «интерполируются» и «до» команда отправляется на сервер, например:
db.collection.aggregate([
{ "$project": {
"mynums": [1,2,3]
}}
])
Чтобы продемонстрировать это, сохраните функцию «только» на сервере:
db.system.js.save({ "_id": "hello", "value": function() { return "hello" } })
Затем попробуйте запустить оператор агрегации:
db.collection.aggregate([
{ "$project": {
"greeting": hello()
}}
])
И это приведет к Исключение:
E QUERY [main] ReferenceError: hello не определено в (shell): 1: 69
blockquote>Это потому, что выполнение выполняется на «клиент», а не «сервер», а функция не существует на клиенте.
В структуре агрегации не может запускаться JavaScript, так как у нее нет никаких условий для этого. Все операции выполняются в собственном коде без запуска JavaScript-движка. Поэтому вместо этого вы используете операторы:
db.collection.aggregate([ { "$project": { "total": { "$add": [ 1, 2 ] }, "field_total": { "$subtract": [ "$gross", "$tax" ] } }} ])
Если вы не можете использовать операторов для получения результатов, то единственный способ запустить код JavaScript - это запустить mapReduce вместо этого, который, конечно, использует механизм JavaScript для взаимодействия с данными из коллекции. И оттуда вы также можете ссылаться на функцию на стороне сервера в своей логике, если вам нужно:
{ "key": 1, "value": 1 }, { "key": 1, "value": 2 }, { "key": 1, "value": 3 } db.system.js.save({ "_id": "square", "value": function(num) { return num * num } }) db.collection.mapReduce( function() { emit(this.key,square(this.value)) }, function(key,values) { return Array.sum(values); }, { "out": { "inline": 1 } } )
Возвраты:
{ "_id": 1, "value": 14 }
Так что это не о том, «как пройти в значении поля ", но на самом деле о том, что структура агрегации никак не поддерживает JavaScript и что то, что вы считали происходящим, на самом деле не так.